【发布时间】:2021-08-30 15:43:01
【问题描述】:
进程正在改变它们不应该改变的东西。
Worker 有一个状态变量(mp.Value)。此值设置为-1,它(Worker)在循环中将其更改为1。
但是,似乎可以通过生成第二个 Worker 将该值 back 重置为 -1,尽管这与原始对没有任何共同之处。这似乎是不可能的。
行为:
当第二个 Worker 启动时,第一个 worker (self.state.value) 的状态被重置为 -1。这被捕获,我们打印出发现了一个错误。
代码:
import multiprocessing as mp
import time
class Worker:
def __init__(self, tag, service_state) -> None:
self.tag = tag
self.local_state = int(service_state.value)
self.state = service_state
self.run_work_loop()
def run_work_loop(self) -> None:
print(f"[{self.tag}] Running... {self.state.value} {self.local_state}")
while True:
if self.state.value != self.local_state:
print(f"[{self.tag}] Illegal change. Shared state: {self.state.value} Local State: {self.local_state}")
break
elif self.state.value == -1:
self.state.value = self.local_state = 1
print(f"[{self.tag}] Set Shared State: {self.state.value} Local State: {self.local_state}.")
if __name__ == "__main__":
mp.Process(target=Worker, args=("A", mp.Value('i', -1))).start()
time.sleep(.03)
mp.Process(target=Worker, args=("B", mp.Value('i', -1))).start()
输出:
[A] Running... -1 -1
[A] Set Shared State: 1 Local State: 1.
[A] Illegal change. Shared state: -1 Local State: 1
[B] Running... -1 -1
[B] Set Shared State: 1 Local State: 1.
【问题讨论】:
-
我怀疑问题与未在主进程中保留对
Values 的引用有关。无论如何,这完全违背了使用共享对象的目的。 -
@jasonharper 正确 - 如果将第一个
mp.Value保存到局部变量,并将其传递给args,问题就会消失。不完全确定为什么,但我认为mp.Value实例在直接传递到args时最终指向相同的东西。 -
我认为这与分配
multiprocessing.Value的方式有关。在内部,它使用ctypes为Value分配内存。我怀疑是因为当您将mp.Value直接传递给args时,它超出了父进程的范围,当您创建第二个Value时,相同的内存位置会被重用。
标签: python multiprocessing python-multiprocessing