Discuz! BBS

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 629|回复: 2

Pool 进程间共享数据

[复制链接]

254

主题

363

帖子

2431

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2431
发表于 2024-9-21 02:39:21 | 显示全部楼层 |阅读模式
使用如下方法:
  1. from multiprocessing import Manager, Pool, cpu_count

  2. def worker(num, data_list):
  3.     data_list.append(num * num)
  4.     return data_list

  5. if __name__ == "__main__":
  6.     with Manager() as manager:
  7.         # 使用Manager创建一个列表,该列表将在多个进程间共享
  8.         shared_data = manager.list()

  9.         # 创建进程池
  10.         with Pool(processes = cpu_count()) as pool:  # 进程池数量不能动态修改,所以可以留空交给Python自由增删。
  11.             results = pool.map(worker, range(5), itertools.repeat(shared_data))

  12.         print(shared_data)  # 在主进程中查看共享数据
复制代码


Manager() 注意。
这里有多种写法:
  1. manager = multiprocessing.Manager()  # 创建共享数据对象
  2.     mg_list = manager.list()
  3.     mg_list.append(0)
  4.     mg_list.append(1)
  5.     mg_list.append(2)
  6.     mg_list[:] = []  # 注意清空的写法
复制代码



使用多进程,与多进程共享对象等的优缺点:
1、多进程共享对象(包括级联对象),作为函数参数传的是值而非引用,一定要注意,如果传入工作函数,则很可能出现值分叉的情况,建议看第3)条。
2、多进程,如果在子进程出错,Python是不报告异常的,这个也不利于查错。
3、建议对象使用全局变量,防止在不同平台的python之间出现兼容问题。(Win平台处理一个作用域内同时global变量和调用该变量报找不到该变量名,实测。)
4、<list proxy>不同于list, 一些功能是没有的。比如删除一个元素,del lsproxy 可用,而 lsproxy.remove(item)不可用。原因是否是<list proxy>没有实现remove方法。
5、注意了以上问题,多进程间共享对象还是绝对必要的并且使用也堪称方便。

回复

使用道具 举报

254

主题

363

帖子

2431

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2431
 楼主| 发表于 2024-10-31 21:34:42 | 显示全部楼层
python multiprocessing 共享对象没有直接提供锁

Python的multiprocessing模块提供了多种方式来共享数据和通信,但没有直接提供锁的机制。如果你需要在多个进程间同步对共享数据的访问,你可以使用multiprocessing.Lock。

以下是一个使用Lock来同步访问共享资源的简单例子:

  1. from multiprocessing import Process, Lock, Manager

  2. def worker(lock, num):
  3.     with lock:  # 使用with语句自动获取和释放锁
  4.         for i in range(10):
  5.             print(f"Worker {num}: {i}")

  6. if __name__ == "__main__":
  7.     lock = Manager.Lock()
  8.     processes = [Process(target=worker, args=(lock, i)) for i in range(5)]
  9.     for p in processes:
  10.         p.start()
  11.     for p in processes:
  12.         p.join()
复制代码

在这个例子中,我们创建了5个进程,每个进程运行worker函数,它们都使用同一个Lock对象来确保同一时间只有一个进程可以访问共享资源(在这个例子中是打印输出)。通过使用with lock:,我们可以保证在with块执行期间,锁会被获取,并且在块执行完毕后自动释放。这样就可以避免竞态条件,保证同步执行。

注意使用multiprocessing实际是线程间共享,不能直接使用Lock(), 而要使用manager.Lock().
回复

使用道具 举报

254

主题

363

帖子

2431

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2431
 楼主| 发表于 2025-2-18 23:33:01 | 显示全部楼层
使用多进程报错"daemonic processes are not allowed to have children"

1. 解释AssertionError: daemonic processes are not allowed to have children错误的含义
这个错误表明,在Python的多进程编程中,守护进程(daemonic process)不允许创建子进程。在Python的multiprocessing模块中,守护进程是那些在程序主进程终止时会自动终止的进程。守护进程的设计初衷是为了在程序正常退出时,不需要手动清理这些进程。然而,由于守护进程会在主进程结束时自动终止,如果它们创建了子进程,这些子进程可能会变成孤儿进程,从而引发潜在的问题。

2. 可能导致这个错误出现的情景
这个错误通常出现在以下几种情景:

‌使用multiprocessing.Pool时‌:当num_workers参数不为0时,multiprocessing.Pool会创建守护进程来执行任务。如果这些任务本身又尝试创建新的进程(例如,在任务内部使用multiprocessing模块),就会触发这个错误。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-4-16 05:09 , Processed in 0.015116 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表