Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理实现简单计数器的简单方法?_Python_Multiprocessing - Fatal编程技术网

Python多处理实现简单计数器的简单方法?

Python多处理实现简单计数器的简单方法?,python,multiprocessing,Python,Multiprocessing,大家好,我现在正在python中使用多处理。我只是想知道是否存在某种简单的计数器变量,当每个进程处理完某个任务时,它们只会增加(有点像总共完成了多少工作) 我在API中查找值,不认为它是可变的。Value确实是可变的;您可以从ctypes模块中指定所需的数据类型,然后可以对其进行修改。下面是一个完整的工作脚本,演示了这一点: from time import sleep from ctypes import c_int from multiprocessing import Value, Loc

大家好,我现在正在python中使用多处理。我只是想知道是否存在某种简单的计数器变量,当每个进程处理完某个任务时,它们只会增加(有点像总共完成了多少工作)


我在API中查找值,不认为它是可变的。

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
值默认情况下是锁定的。这是正确的,因为即使一个赋值由多个操作组成(例如,赋值一个字符串,可能是多个字符),那么这个赋值也是原子的。但是,当递增计数器时,仍然需要一个外部锁,如我的示例所示,因为递增会加载当前值,然后递增,然后将结果分配回

因此,如果没有外部锁,您可能会遇到以下情况:

  • 进程1读取(原子)计数器的当前值,然后将其递增
  • 在进程1将递增的计数器分配回
    值之前,会发生上下文切换
  • 进程2读取(原子地)计数器的当前(未增量)值,将其递增,并将递增的结果(原子地)分配回
  • 进程1(原子地)分配其增量值,消除进程2执行的增量

默认情况下,值访问受到锁的保护。您需要在此处使用“from future import with_statement”,不是吗?@Edward:如果您使用的是Python 2.5,您确实需要将来的导入,我在编写代码时使用的是Python 2.6,因此没有必要。既然使用了锁,为什么必须使用值?为什么不能用一个简单的
int
来代替呢?@a-B-B:因为
Value
允许我们跨进程共享相同的
int
。调用
do\u something
调用
increment
是在一个单独的进程中进行的,因此,如果我们的值是一个简单的int,那么它不会在原始父进程中递增。