SEO:
- Python Synchronized variable value doesn't change in global context
- Synchronized value not modified in main process
- Synchronized value not shared between processes
在Python的multiprocessing
库里面,有multiprocessing.sharedctypes.synchronized
这个用来在不同进程间共享数据的wrapper类型,默认使用一个重入锁RLock
来维护数据一致性。在这次重新学习Python之前,我用的是Python 3.6,当时虽然使用过mp库的一些皮毛,但未曾深入考虑过多进程程序在不同操作系统上的不同行为,以及它们可能的影响。
这次学习时,遇到一个问题:当我在macOS系统用Python 3.12在全局context里创建一个multiprocessing.sharedctypes.Value
变量的时候,如果我在一个新的进程里访问这个变量,其值并未在不同进程之间保持同步。和Eric Greene老师讨论后,才发现自从Python 3.8以来,不同操作系统的新建进程的方式发生了变化:
- Linux系统始终使用
fork
来创建新的进程。在fork的时候,父进程的所有资源都被子进程继承,因此在父进程全局定义的同步变量,同样可以被子进程访问,所以数据一致性得以保留 - Windows系统始终使用
spawn
,即创建一个新的Python解释器进程的方法来实现多进程。相当于“多开”Python,因此overhead更多,效率更低,但是这是Windows系统本身的局限。在这种情况下,子进程只继承父进程中,用来启动新进程的run()
方法所需的资源。 - macOS系统在Python 3.8以前是使用fork,之后改为使用spawn,因此有些多进程行为发生了改变。(macOS仍旧可以设置成使用fork,但Python官方不推荐)
在我的例子里面,因为Synchronized变量在父进程的全局声明,因此在Windows和macOS系统上,它不会被子进程所继承,因此不同进程之间的值产生差异;而在Linux系统上,所有父进程的资源都被继承,所以子进程能改变它的值。
这便造成了我所看到的现象:我的代码在macOS上全局同步变量没有变;而别人的Linux系统则运行正常,变量在所有进程间同步。
参考阅读:
Top comments (0)