从多处理中使用Pool时如何获取函数中的进程号

Posted

技术标签:

【中文标题】从多处理中使用Pool时如何获取函数中的进程号【英文标题】:How to get the process number in the function when using Pool from multiprocessing 【发布时间】:2020-11-05 01:34:58 【问题描述】:

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

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

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

【问题讨论】:

继续阅读multiprocessing.Process.pid 【参考方案1】:

您使用的是multiprocessing.dummy.Pool,即actually a thread 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 开始计数。

【讨论】:

我刚刚尝试导入from multiprocessing.pool import ThreadPool 并使用threading.current_thread().ident 来获取ID,但我仍然得到这些数字(27772,22660),这显然不是线程数,因为我使用的是3个线程所以这些数字应该是(1,2 或 3)我在这里做错了吗? 没有由 Python 分配的线程号从 1 开始计数。 @UsamaIlyas 如果您真的希望池中的每个线程都从一个开始计数,您可以通过自己分配 ID 来实现。我更新了我的答案来证明这一点。 @UsamaIlyas 数字应为(1,2 或 3):使用 multiprocessing.Process.name 将显示 Process-N1:N2:…:Nk @stovfl 那行不通,因为他使用的是线程,而不是进程。 threading.current_thread().name 将显示 Thread-<#>,其中 # 从 1 开始计数。

以上是关于从多处理中使用Pool时如何获取函数中的进程号的主要内容,如果未能解决你的问题,请参考以下文章

将标准输出从多处理重定向到 Tkinter 文本小部件

我可以在 Pool.imap 调用的函数中使用多处理队列吗?

multiprocessing.Pool:如何在旧进程完成时启动新进程?

多处理:如何在类中定义的函数上使用 Pool.map?

Java如何得到当前进程ID号

python执行多进程时,如何获取函数返回的值