你好,我是新来的,我想问一个问题。现在我正在使用python多处理来处理队列中的数据。示例我有3个函数来从队列中计算数据,并且在队列中我有3个数据。是否可以将流水线技术与多处理结合使用以使其更快?
在此代码中,我尝试使用多处理队列在多处理进程之间进行通信,并使用Lock防止其他进程在从上一个功能完成之前在队列中使用数据。但是
from multiprocessing import Process, current_process, cpu_count, Queue, Pool, Lock, Array
from threading import Thread, current_thread
import time
import os
def a(pid, q1, q2, lock):
while not q1.empty():
data = q1.get()
print("data from q1 is %s" % data)
# for i in range(1000000):
new_data = data*2
lock.acquire()
q2.put(new_data)
print(pid)
lock.release()
def b(pid, q2, q3, lock):
while not q2.empty():
data = q2.get()
print("data from q2 is %s" % data)
# for i in range(1000000):
lock.acquire()
new_data = data*3
q3.put(new_data)
print(pid)
lock.release()
def c(pid, q3, q4, lock):
while not q3.empty():
data = q3.get()
print("data from q3 is %s" % data)
# for i in range(1000000):
lock.acquire()
new_data = data*4
q4.put(new_data)
print(pid)
lock.release()
if __name__ == "__main__":
number = [1,2,3]
lock = Lock()
q1 = Queue()
q2 = Queue()
q3 = Queue()
q4 = Queue()
for data in number:
q1.put(data)
p1 = Process(target=a,args=(1, q1, q2, lock))
p2 = Process(target=b,args=(2, q2, q3, lock))
p3 = Process(target=c,args=(3, q3, q4, lock))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
for i in range(q4.qsize()):
print(q4.get())
我希望流水线的序列应该像f1这样执行| f1 f2 | f1 f2 f3 | f2 f3 | f3,如果我的信息正确,则队列中的解决方案是24、48、72。我尽力解释这些事情应该如何工作,因为这是我第一次在stackoverflow中提出问题,而且我的英语水平也不高,我也确实需要帮助。
答案 0 :(得分:1)
您的问题是您正在使用q.empty()
终止循环。其中一些Queues
一开始将为空,而这些Process
将终止为时过早。您需要一种不同的技术来让p2
和p3
进程知道何时退出。
这是您的代码的修改,使用None
作为队列中的标志来指示完成时:
from multiprocessing import Process, current_process, cpu_count, Queue, Pool, Lock, Array
from threading import Thread, current_thread
import time
import os
def a(pid, q1, q2, lock):
while not q1.empty():
data = q1.get()
print("data from q1 is %s" % data)
# for i in range(1000000):
new_data = data*2
lock.acquire()
q2.put(new_data)
print(pid)
lock.release()
q2.put(None)
def b(pid, q2, q3, lock):
while True:
data = q2.get()
if data is None:
q3.put(None)
return
print("data from q2 is %s" % data)
# for i in range(1000000):
lock.acquire()
new_data = data*3
q3.put(new_data)
print(pid)
lock.release()
def c(pid, q3, q4, lock):
while True:
data = q3.get()
if data is None:
return
print("data from q3 is %s" % data)
# for i in range(1000000):
lock.acquire()
new_data = data*4
q4.put(new_data)
print(pid)
lock.release()
if __name__ == "__main__":
number = [1,2,3]
lock = Lock()
q1 = Queue()
q2 = Queue()
q3 = Queue()
q4 = Queue()
for data in number:
q1.put(data)
p1 = Process(target=a,args=(1, q1, q2, lock))
p2 = Process(target=b,args=(2, q2, q3, lock))
p3 = Process(target=c,args=(3, q3, q4, lock))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
for i in range(q4.qsize()):
print(q4.get())
此外,您实际上不需要Lock
。根据{{3}}:
队列模块实现多生产者,多消费者队列。它 当必须进行信息处理时,在线程编程中特别有用 在多个线程之间安全地交换。此中的Queue类 模块实现了所有必需的锁定语义。