【问题标题】:Multiprocessing in Python creates single processPython中的多处理创建单个进程
【发布时间】:2020-11-29 21:32:36
【问题描述】:

我在 python 中遇到了多处理问题,请参阅下面的代码:

processArray = []
downtimeObj = []
for x in range(0,len(clientMaster)):
    downtimeObj.append(Downtime(clientMaster[x]))
    processArray.append(multiprocessing.Process(target=downtimeObj[x].live(),))
    for j in range(len(processArray)):
        processArray[j].start()
    for z in range(len(processArray)):
        processArray[z].join()

这里我有一个进程数组“processArray”和一个停机时间类的对象数组。在我的客户端主服务器中,我尝试遍历我拥有的客户端数量并为每个客户端创建一个对象,从而为每个客户端创建一个进程。

当前代码创建单个进程并按时间顺序运行 live() 函数。

我希望所有客户端都有单独的进程,并且 object.live() 函数可以同时运行。

【问题讨论】:

  • 你的代码有正确的缩进吗?因为现在你的 processArray 里面总是有一个 Process 项目。
  • join() 阻塞代码直到进程结束运行 - 所以在循环中使用它 for x 是错误的想法 - 在启动一个进程后,它将等待它结束,然后再运行另一个进程。您应该在循环外运行它。我认为你应该在 for x 循环之外运行 .start()
  • process 需要没有() 的函数名称,因此您应该使用没有()target=downtimeObj[x].live。使用(),你在主线程中运行这个函数,并使用这个函数的结果作为目标——比如result = downtimeObj[x].live()Process(target=result)
  • 你应该学会在没有range(len())的情况下使用for-loop

标签: python python-3.x process multiprocessing python-multiprocessing


【解决方案1】:

您应该更改缩进和仅创建所有进程的第一个运行循环。运行.start() 的下一个循环。最后循环使用.join()

Process()(类似于Thread())需要不带()的函数名,所以稍后它可以使用()开始新进程。

target=downtimeObj[x].live

如果您使用(),那么它会在当前进程中运行live(),并将其结果作为Process() 的参数发送

result = downtimeObj[x].live()
Process(target=result)

您也可以学习在没有range(len()) 的情况下使用for-loop - 它会更具可读性。

processArray = []
downtimeObj = []

# --- loop ---

for item in clientMaster:
    obj = Downtime(item)
    downtimeObj.append(obj)
    p = multiprocessing.Process(target=obj.live)
    processArray.append(p)

# --- after loop ---

for p in processArray:
    p.start()

for p in processesArray:
    p.join()

或者你至少应该 .join() 在第一个循环之外运行

processArray = []
downtimeObj = []

# --- loop ---

for item in clientMaster:
    obj = Downtime(item)
    downtimeObj.append(obj)
    p = multiprocessing.Process(target=obj.live)
    processArray.append(p)
    p.start()

# --- after loop ---

for p in processesArray:
    p.join()

编辑:

如果您需要发送参数,请使用元组,即。 (value1, value2)

Process(target=obj.live, args=(value1, value2))

并将运行live(value1, value2)

对于单个参数,您还需要元组,即。 (value1,)
它需要 ,( ) 内创建具有单个元素的元组。

Process(target=obj.live, args=(value1,))

并将运行live(value1)

您也可以在文档Process中看到它


编辑:

如果您想使用Pool 始终只运行 5 个进程并获得所有结果

from multiprocessing import Pool

# --- function for Process ---

def my_function(item, arg1, arg2):
    obj = Downtime(item)
    return obj.live(arg1, arg2)

# --- create arguments for all processes ---

arguments = []

for item in clientMaster:
    arguments.append( (item, value1, value2) )

# --- use Pool and wait for all results ---

with Pool(5) as p:
     results = p.starmap(my_function, arguments)

# --- display all results ---

print(results)

【讨论】:

  • 如果我需要在实时函数中传递参数怎么办?你能做一个相同的编辑吗?
  • 我添加它来回答。
  • 我还添加了Pool 的示例并获得了结果
  • 使用 Process(target=obj.live, args=(value1,)) 合适吗?
  • 你是对的 - 它应该与 args= 一起使用,因为在命名参数 target= 之后,它还需要具有命名参数的其他值。我在回答中更正了它
猜你喜欢
  • 2017-04-05
  • 2018-10-27
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 2020-06-24
相关资源
最近更新 更多