首页 > 解决方案 > 从多处理中使用Pool时如何获取函数中的进程号

问题描述

当使用池进行多处理时,我试图在我的函数中获取当前进程号。这是我用来测试的代码:

from multiprocessing.dummy import Pool
import itertools

def function(a,b,c):
    print("Value of a: {} Value of b : {} Constant : {}".format(a,b,c))

a = [4,5,6,7,8]
b = [11,12,13,14,15]

pool = Pool(3)
pool.starmap(function, zip(a,b,itertools.repeat(50)))
pool.close()
pool.join()

现在我的函数输出如下所示:

Value of a: 4 Value of b : 11 Constant : 50
...

我真正想要的是在我的函数中获取当前进程号,以准确地通知我哪个进程正在运行函数的当前迭代像这样:

Value of a: 4 Value of b : 11 Constant : 50 Process : 1
Value of a: 5 Value of b : 12 Constant : 50 Process : 2
Value of a: 6 Value of b : 13 Constant : 50 Process : 3

我尝试使用multiprocessing.current_process().ident 但它显示了这个输出:

Value of a: 4 Value of b : 11 Constant : 50 Thread : 33084
Value of a: 5 Value of b : 12 Constant : 50 Thread : 33084
Value of a: 6 Value of b : 13 Constant : 50 Thread : 33084

我应该使用多处理中的任何其他方法或属性来获取当前进程号吗?

标签: python-3.xmultiprocessingthreadpoolpython-multiprocessingpool

解决方案


您正在使用multiprocessing.dummy.Pool,它实际上是一个线程池,而不是进程池。所以一切仍然在一个进程中运行,这意味着每个线程都将具有相同identmultiprocesing.current_process(). 如果您打算使用线程池,则可以使用threading.current_thread().ident来获取每个线程的唯一 ID。

如果您打算使用进程池,那么multiprocessing.current_process().ident一旦切换,它将按照您期望的方式工作。您也可以使用os.getpid(),它(至少在 Linux 上)返回相同的值。

如果您希望每个线程都有一个从 1 开始计数的单调递增 ID,您可以通过在每个线程启动时自己分配标识符来实现,如下所示:

from multiprocessing.dummy import Pool
import itertools

def function(a,b,c):
    print("Value of a: {} Value of b : {} Constant : {} ID: {}".format(a,b,c,d.id))

a = [4,5,6,7,8]
b = [11,12,13,14,15]

d = threading.local()
def set_num(counter):
    d.id = next(counter) + 1

pool = Pool(3, initializer=set_num, initargs=(itertools.count(),))

pool.starmap(function, zip(a,b,itertools.repeat(50)))
pool.close()
pool.join()

itertools.count()是线程安全的,因此可用于在初始化池中的每个线程时为其分配唯一标识符。然后,您可以使用一个threading.local对象来存储每个线程的唯一 ID。

如果你不关心实际上有一个整数值,你可以使用threading.current_thread().name,它将打印一个具有整数后缀的字符串,从 1 开始计数。


推荐阅读