Python 多进程实现简单计数器的简单方法?

9 投票
1 回答
8983 浏览
提问于 2025-04-15 13:23

大家好,我现在在用Python做多进程编程。我想知道有没有一种简单的计数器变量,能够让每个进程在完成某个任务后都能增加一下(就像是记录总共完成了多少工作)。

我查了一下Value的API,感觉它好像不能被修改。

1 个回答

27

Value 确实是可以改变的;你需要从 ctypes 模块中指定你想要的数据类型,然后它就可以被修改。下面是一个完整的、可以运行的脚本,演示了这一点:

from time import sleep
from ctypes import c_int
from multiprocessing import Value, Lock, Process

counter = Value(c_int)  # defaults to 0
counter_lock = Lock()
def increment():
    with counter_lock:
        counter.value += 1

def do_something():
    print("I'm a separate process!")
    increment()

Process(target=do_something).start()
sleep(1)
print counter.value   # prints 1, because Value is shared and mutable

补充说明:Luper 在下面的评论中正确指出,Value 的值默认是被锁定的。这是对的,意思是即使一个赋值操作涉及多个步骤(比如赋值一个可能包含很多字符的字符串),这个赋值操作也是原子的,也就是说它要么完成,要么不完成,不会出现中间状态。但是,当你要增加一个计数器时,你仍然需要一个外部锁,就像我在示例中提供的那样,因为增加计数器的过程是先读取当前值,然后增加,再把结果赋值回 Value

所以如果没有外部锁,你可能会遇到以下情况:

  • 进程 1 读取(原子性地)计数器的当前值,然后增加它
  • 在进程 1 还没把增加后的计数器值赋回 Value 之前,发生了上下文切换
  • 进程 2 读取(原子性地)计数器当前(未增加的)值,增加它,并把增加后的结果(原子性地)赋回 Value
  • 进程 1 把它增加后的值(原子性地)赋值回去,这样就覆盖了进程 2 的增加结果

撰写回答