正在为 python 中的两个共享 objects 同步 read/write 操作

syncing read/write operations for two shared objects in python

假设我使用 multiprocessing.Manager 创建两个共享 objects 并将它们传递给子进程,该子进程开始写入这些 objects:

manager = multiprocessing.Manager()
a = manager.list()
b = manager.list()
subprocess = MyProcess(a,b)
subprocess.start()  # writing to a and b starts here

# inspect a and b - in what order will changes appear?

有没有办法确保这些写入在 parent 进程中反映的顺序与在子进程中执行写入的顺序相同?如果我 register() 一个 class 有两个成员,子进程对这两个成员进行更改怎么办?

是否有更笼统地回答这些“操作顺序”问题的参考资料? (我在文档中找不到这个)。例如:如果我们生成第二个子进程,subprocess_2,它也在 ab 上进行一些写入和读取,我们可以说什么顺序变化将反映在parent 和 subprocess_2?

简单、详细的示例:按照 Booboo 的示例,如果 MyProcess(multiprocessing.Process 的子class)像这样实现 run()

def run(self) :
    a.append(1)
    b.append(2)

然后 如果我们等待足够长的时间,我们知道 parent 进程将看到 a == [1]b == [2]。问题是我们可以在两者之间看到哪些可能的状态。如果管理器中存在某种全局同步,我们将只能看到 a,b 的以下成对值:[],[][1],[] 或最终状态 [1],[2] .但是如果没有这样的同步,我们也许能够瞥见 [],[2](例如,如果关于附加到 b 的消息更快地到达 parent,或者轮询的顺序queues 不是我们所期望的(我们期望什么?))。我希望不必查看源代码(在未来的版本中也可能会更改),而是获得一般保证(如果有的话)。希望这能澄清问题。

在您显示的示例中,您正在处理一个 managed 列表。此列表存在于执行 manager = multiprocessing.Manager() 时创建的进程中。变量 ab 实际上是 proxy 对象。当在这些代理上调用方法时,将执行从一个进程的地址 space 到 SynchManager 的远程方法调用(通信机制是 Linux 下的套接字和 Windows 下的命名管道)地址 space(multiprocessing.SyncManager 是通过调用 multiprocessing.Manager() 创建的 class),实际方法由 SyncManager 地址中的线程 运行 执行space 侦听套接字连接并且在方法调用完成之前不会回复连接(return 返回给调用者)。

更新

根据 OP 的更新问题,ab 列表的可能状态按时间顺序排列:

  1. a -> [], b -> []
  2. a -> [1], b -> []
  3. a -> [1], b -> [2]

没有其他可能的状态,因为对 a.append(1) 的调用将阻塞,直到 a 列表附加了值 1.想象一下下面的代码:

a.append(1)
# How can the following assertion fail?
# Who would implement a list in such a way where this could fail?
assert(1 in a)
b.append(b)