多进程:在queu中标识进程

2024-09-30 06:29:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个多进程程序,可以获取响应时间不同的网页。结果根据FIFO规则存储在进程队列中。我想通过进程号来识别队列中的结果。这是我的测试平台,也是到目前为止我使用两个队列所取得的成果。还有别的办法吗?我试图使用全局列表来存储结果,但这两个进程似乎不共享相同的内存空间。在

#!/usr/bin/python3.2

import time
from multiprocessing import Process, Queue

def myWait(processNb, wait, resultQueues):
    startedAt = time.strftime("%H:%M:%S", time.localtime())
    time.sleep(wait)
    endedAt = time.strftime("%H:%M:%S", time.localtime())
    resultQueues[processNb].put('Process %s started at %s wait %s ended at %s' % (processNb, startedAt, wait, endedAt))

# queue initialisation
resultQueues = [Queue(), Queue()]

# process creation arg: (process number, sleep time, queue)
proc =  [
    Process(target=myWait, args=(0, 2, resultQueues,)),
    Process(target=myWait, args=(1, 1, resultQueues,))
    ]

# starting processes
for p in proc:
    p.start()

for p in proc:
    p.join()

# print results
print(resultQueues[0].get())
print(resultQueues[1].get())

Tags: importtime队列queue进程procprocessprint
2条回答
  • mp.Processs可以被赋予一个name参数,目标 函数myWait可以使用mp.current_process().name进行访问。 所以不需要传递processNb。在
  • 尽量减少进程间通信。而不是传递 格式化字符串通过队列,只需传递字符串的部分 这将在元组中发生变化:(name, wait, startedAt, endedAt)。在

所以,你可以用这样一个队列:

import time
import multiprocessing as mp

def myWait(wait, resultQueue):
    startedAt = time.strftime("%H:%M:%S", time.localtime())
    time.sleep(wait)
    endedAt = time.strftime("%H:%M:%S", time.localtime())
    name = mp.current_process().name
    resultQueue.put(
        (name, wait, startedAt, endedAt))


# queue initialisation
resultQueue = mp.Queue()

# process creation arg: (process number, sleep time, queue)
proc =  [
    mp.Process(target=myWait, name = '0', args=(2, resultQueue,)),
    mp.Process(target=myWait, name = '1', args=(1, resultQueue,))
    ]

# starting processes
for p in proc:
    p.start()

for p in proc:
    p.join()

# print results
for p in proc:
    name, wait, startedAt, endedAt = resultQueue.get()
    print('Process %s started at %s wait %s ended at %s' %
          (name, startedAt, wait, endedAt))

当所有的进程都使用共享空间时,{cdm>不会共享所有的进程。这意味着,要在进程之间共享的任何内容都必须经过进程之间的显式连接,例如Queue。在

如果您想要合并所有进程的结果,实际上您可以使用一个结果队列—多个进程(和多个线程)一次访问它们非常安全。然后,您的所有工作人员都可以将结果插入该队列,主进程可以在它们进入时读取它们。在

以下是修改后的代码以使用单个队列:

#!/usr/bin/python3.2

import time
from multiprocessing import Process, Queue

def myWait(processNb, wait, results):
    startedAt = time.strftime("%H:%M:%S", time.localtime())
    time.sleep(wait)
    endedAt = time.strftime("%H:%M:%S", time.localtime())
    results.put('Process %s started at %s wait %s ended at %s' % (processNb, startedAt, wait, endedAt))

# queue initialisation
results = Queue()

# process creation arg: (process number, sleep time, queue)
proc =  [
    Process(target=myWait, args=(0, 2, results,)),
    Process(target=myWait, args=(1, 1, results,))
    ]

# starting processes
for p in proc:
    p.start()

for p in proc:
    p.join()

# print results
print(results.get())
print(results.get())

如果您想在不必读取字符串的情况下标识每个结果来自哪个进程,则可以轻松地将其添加为一个2元组。这将更改代码如下(我只显示了更改的部分):

^{pr2}$

这有帮助吗?在

编辑:正如另一个响应者非常正确地指出的那样,传递更多的结构化数据可能比传递字符串更好,但是为了便于解释,我试图保持我的示例与您的示例相似。事实上,为了使将来的更改更容易,我将使用一些可以按名称索引的东西,而不是元组(因此,您不必仅限于在末尾添加项)。在

您可以使用自己的类,也可以使用一个collections.namedtuple来完成这项工作(如果您希望以后扩展已经使用元组来代替名称的代码,允许逐步迁移,则后者特别有用)。在

请记住(据我所知),您可以通过队列传递任何可以pickled的内容。在

相关问题 更多 >

    热门问题