如何将python多处理和流水线技术相结合?

时间:2019-04-15 19:04:55

标签: python parallel-processing pipeline

你好,我是新来的,我想问一个问题。现在我正在使用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中提出问题,而且我的英语水平也不高,我也确实需要帮助。

1 个答案:

答案 0 :(得分:1)

您的问题是您正在使用q.empty()终止循环。其中一些Queues一开始将为空,而这些Process将终止为时过早。您需要一种不同的技术来让p2p3进程知道何时退出。

这是您的代码的修改,使用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类   模块实现了所有必需的锁定语义。