您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在Python中从线程调用多处理安全吗?

在Python中从线程调用多处理安全吗?

听起来好像当前线程派生时,该进程中所有锁的状态都已复制到子进程中(这似乎是设计错误,并且肯定会死锁)。

这不是设计错误,而是fork()早于单进程多线程。所有锁的状态都被复制到子进程中,因为它们只是内存中的对象。进程的整个地址空间都按fork复制。仅有一些不好的选择:要么通过fork复制所有 线程,要么拒绝多线程应用程序中的派生。

因此,fork()除非在子进程之后execve()exit()在子进程中进行操作,否则永远都不是安全的事情。

是否可以在各处用multiprocessing.Lock替换threading.Lock来避免此问题,并允许我们安全地组合线程和fork?

没有什么可以安全地组合线程和派生的,这是无法做到的。

问题是,当一个进程中有多个线程时,在fork()系统调用之后,您将无法继续在POSIX系统中安全地运行该程序。

例如,Linux手册fork(2)

* 在fork(2)进入多线程程序之后,子级只能安全地调用异步信号安全函数(请参阅参考资料signal(7)),直到它调用为止execve(2)

也就是说,可以fork()在多线程程序中然后仅调用异步信号安全的 函数(这是 函数的相当有限的子集),直到子进程已被另一个可执行文件替换!

子进程中的不安全C函数调用例如

因此,子进程实际上可以安全地执行的操作很少。不幸的是,cpython核心开发人员一直低估了由此引起的问题。甚至现在文档说:

请注意,安全地分叉多线程进程是 。

委婉的说法是“不可能”。

如果您 使用start方法,则可以安全地 具有多个控制线程的Python进程中使用多重处理。在Python 3.4+中,@L_301_4@。在包括所有Python 2在内的早期Python版本中,POSIX系统始终表现为被指定为启动方法。这将导致不确定的行为。 __forkfork

问题不仅限于threading.Lock对象,还包括C标准库,C扩展等持有的 锁。更糟糕的是,大多数时候人们会说“它对 ” …直到它停止工作。

甚至在某些情况下,看似单线程的Python程序实际上在MacOS X中是多线程的,在使用多处理时会导致失败和死锁。

一个问题是,所有打开的文件句柄,它们的使用,共享套接字在派生的程序中可能表现得很奇怪,但是即使在单线程程序中也是如此。

TL; DR:multiprocessing在多线程程序中使用,带有C扩展名,打开的套接字等:

python 2022/1/1 18:31:37 有432人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶