DEV Community

Ting
Ting

Posted on

Synchronized 变量在不同操作系统的不同行为

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系统则运行正常,变量在所有进程间同步。

参考阅读:

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay