我有一个Producer进程,它运行并将结果放入队列中 我还有一个Consumer函数,它从队列中获取结果并处理它们,例如:
def processFrame(Q,commandsFile):
fr = Q.get()
frameNum = fr[0]
Frame = fr[1]
#
# Process the frame
#
commandsFile.write(theProcessedResult)
我想使用多个进程运行我的使用者功能,它们的编号应由用户设置:
processes = raw_input('Enter the number of process you want to use: ')
我尝试使用Pool:
pool = Pool(int(processes))
pool.apply(processFrame, args=(q,toFile))
当我尝试这个时,它返回一个RuntimeError:Queue对象只应通过继承在进程之间共享。 这是什么意思?
我还尝试使用进程列表:
while (q.empty() == False):
mp = [Process(target=processFrame, args=(q,toFile)) for x in range(int(processes))]
for p in mp:
p.start()
for p in mp:
p.join()
这个似乎在运行,但并不像预期的那样。 它在Queue的同一帧上使用多个进程,队列是否有锁? 此外,在这种情况下,我允许使用的进程数量必须除以没有残留的帧数(提醒) - 例如: 如果我有10帧我只能使用1,2,5,10个进程。如果我使用3,4 ..它将创建一个过程,而Q空,不会工作。
答案 0 :(得分:0)
如果你想回收过程直到q为空,你应该尝试这样做:
代码1:
def proccesframe():
while(True):
frame = queue.get()
##do something
你的过程将被阻止,直到队列中有东西为止
我不认为在菜单部分使用multiproccess很好,你应该在生产者身上使用它们。
如果你想在队列为空时终止procces,你可以这样做:
代码2:
def proccesframe():
while(!queue.empty()):
frame = queue.get()
##do something
terminate_procces()
如果你想在消费者部分中使用多个过程,只需做一个简单的循环并添加code2,那么当你完成对队列的处理时,你就可以关闭你的过程。
答案 1 :(得分:0)
我不完全确定您要从解释中完成什么,但是您是否考虑过使用multiprocessing.Pool及其方法map或map_async?
from multiprocessing import Pool
from foo import bar # your function
if __name__ == "__main__":
p = Pool(4) # your number of processes
result = p.map_async(bar, [("arg #1", "arg #2"), ...])
print result.get()
它在无序(!)迭代中收集函数的结果,你可以随意使用它。
<强>更新强>
我认为你不应该使用队列并且更直接:
from multiprocessing import Pool
def process_frame(fr): # PEP8 and see the difference in definition
# magic
return result # and result handling!
if __name__ == "__main__":
p = Pool(4) # your number of processes
results = p.map_async(process_frame, [fr_1, fr_2, ...])
# Do not ever write or manipulate with files in parallel processes
# if you are not 100% sure what you are doing!
for result in results.get():
commands_file.write(result)
更新2
from multiprocessing import Pool
import random
import time
def f(x):
return x*x
def g(yr):
with open("result.txt", "ab") as f:
for y in yr:
f.write("{}\n".format(y))
if __name__ == '__main__':
pool = Pool(4)
while True:
# here you fetch new data and send it to process
new_data = [random.randint(1, 50) for i in range(4)]
pool.map_async(f, new_data, callback=g)
如何做到这一点的一些例子,我将算法更新为&#34;无限&#34;,它只能通过中断或从外部杀死命令来关闭。您也可以使用apply_async,但这会导致结果处理速度变慢(取决于处理速度)。
我也尝试在全局范围内使用长时间打开的result.txt,但每次都遇到死锁。