多处理怎么样。事件传递到后台的子进程?

How is a multiprocessing.Event passed to a child process under the hood?

提问人:Joerg 提问时间:10/29/2023 更新时间:10/31/2023 访问量:31

问:

根据这个 SO 答案,当 a 传递给子进程时,实际发送的是从管道中获取的文件描述符(或句柄),而不是酸洗对象本身。multiprocessing.QueueQueue

这是如何工作的,例如,当做一个multiprocessing.Event

cancel_event = multiprocessing.Event()
process = multiprocessing.Process(target=worker_function, args=(cancel_event, ))

我认为还必须有一些与操作系统相关的东西被发送到子进程。这也是像队列一样的管道句柄吗?Event

Python 事件 多处理 pickle

评论


答:

1赞 Aaron 10/31/2023 #1

Event 类是 a 的非常简单的扩展,还有一个附加的 .A 包含一个和几个更多的信号量,而 Lock 只是一个最大值只有 1 的信号量,所以问题真的可以归结为如何将 a 传递给另一个进程......ConditionSemaphoreConditionLockSemaphoreSemaphore


使用 Spawning 上下文创建进程或通过队列或管道发送锁时,将使用以下命令对其进行序列化:pickle

和 的基类是 ,它定义了 __getstate____setstate__ 方法,以便能够使用协议通过管道发送。SemaphoreLockSemLockpickle

在发送端,将获得可以发送的锁的句柄。在 Windows 上,不能简单地获取 CreateSemaphore 返回的句柄并在另一个进程中使用它,因此首先使用 DuplicateHandle 对其进行复制,为其提供将使用它的目标进程。在 *nix 上,句柄被简单地复制。__getstate__

在接收端,句柄编号与唯一名称和一些其他属性一起使用,这些属性被复制以重建信号量。这是一个非常简单的过程,将值解压缩到一个新结构中,该结构包含底层操作系统级别信号量的句柄。SemLockObject


使用分叉上下文创建进程时

新进程获取父进程内存的完整副本,包括包含对信号量句柄的引用的对象(请参阅:分叉和进程写入时复制)。由于此处不涉及窗口,因此句柄值的简单复制是有效的。

评论

0赞 Joerg 11/3/2023
非常感谢您的详细回答。因此,基本上它归结为传递由操作系统已知/管理的整数值。我理解正确吗?
0赞 Aaron 11/3/2023
@Joerg是的,尽管也有一些“使用该整数的许可”......在这种情况下,窗口的限制性更强,需要额外的步骤才能使句柄可共享。