通过函数调用与Python中的Process进行通信3.4多处理

时间:2015-01-21 15:44:20

标签: python python-multiprocessing

我创建了一个新类,它是multiprocessing.Process的子类,我想在这个类上调用方法。这些方法改变了类成员但没有参数,我认为应该透明地工作。例如,在下面的MWE中,我创建了一个继承自Process的类,并且有一个stop()函数,它只设置一个实例成员标志。设置此标志虽然run()方法似乎没有注意到更改。当我从线程继承时,这一切似乎都有效。思考,思考?

from queue import Empty
import multiprocessing


class Worker(multiprocessing.Process):
    def __init__(self, queue):
        multiprocessing.Process.__init__(self) # , daemon=True)
        self.queue = queue
        self.close = False

    def stop(self):
        self.close = True
        print(self.close)

    def run(self):
        while (not self.close) or self.queue.qsize() > 0:
            print(self.close)
            print(self.queue.qsize())
            for item in range(0, self.queue.qsize()):
                try:
                    self.queue.get_nowait()
                except Empty:
                    continue

queue = multiprocessing.Queue()
dbq = Worker(queue)
dbq.start()
queue.put("d")
dbq.stop()
dbq.join()

2 个答案:

答案 0 :(得分:3)

您必须使用类似multiprocessing.Value的内容来处理进程之间的同步。

示例代码:

from queue import Empty
from ctypes import c_bool
import multiprocessing

class Worker(multiprocessing.Process):
    def __init__(self, queue):
        multiprocessing.Process.__init__(self) # , daemon=True)
        self.queue = queue
        self.close = multiprocessing.Value(c_bool, False)

    def stop(self):
        self.close.value = True
        print(self.close)

    def run(self):
        while (not self.close.value) or self.queue.qsize() > 0:
            print(self.close)
            print(self.queue.qsize())
            for item in range(0, self.queue.qsize()):
                try:
                    self.queue.get_nowait()
                except Empty:
                    continue

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    dbq = Worker(queue)
    dbq.start()
    queue.put("d")
    dbq.stop()
    dbq.join()

答案 1 :(得分:1)

进程不会以与线程相同的方式与父进程共享内存空间。当进程为fork时,它将获得父内存的新副本,因此您无法像使用线程一样轻松共享(实际上......实际上有copy-on-write)。

我建议为了杀死工人,你使用像Event这样的同步原语,因为工作人员通常会因为发生的事情而被杀死。

你最终会得到这样的结果(通知,工人没有stop方法):

from queue import Empty
import multiprocessing


class Worker(multiprocessing.Process):
    # added the event to the initializing function
    def __init__(self, queue, close_event):
        multiprocessing.Process.__init__(self) # , daemon=True)
        self.queue = queue
        self.close = close_event

    def run(self):
        while (not self.close.is_set()) or self.queue.qsize() > 0:
            print(self.close)
            print(self.queue.qsize())
            for item in range(0, self.queue.qsize()):
                try:
                    self.queue.get_nowait()
                except Empty:
                    continue

queue = multiprocessing.Queue()
# create a shared event for processes to react to
close_event = multiprocessing.Event()
# send event to all processes
dbq = Worker(queue, close_event)
dbq.start()
queue.put("d")
# set the event to stop workers
close_event.set()
dbq.join()