如何在不传递参数的情况下处理多个进程中的输出?

时间:2017-01-27 07:40:52

标签: python python-2.7 multiprocessing multifile

如何将队列共享到多个进程,多个文件中的这些进程的代码,我不想将队列作为参数传递。

我尝试解决问题,但失败了。 我有三个文件

main.py

from p_1 import test
from p_2 import queue_run
import multiprocessing


if __name__ == '__main__':
    process_1 = multiprocessing.Process(target=test)
    process_2 = queue_run()
    process_1.start()
    process_2.start()
    process_1.join()
    process_2.join()

p_1.py

import time
from p_2 import queue_put


def test():
    var = ['a', 'b', 'c', 'd']
    for v in var:
        queue_put('something : ' + v)
        time.sleep(0.8)

p_2.py

import multiprocessing

queue = multiprocessing.Queue()


def queue_put(something):
    queue.put(something)

class queue_run(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)

    def run(self):
        while True:
            try:
                data = queue.get(timeout=1)
                print data
            except:
                break

然后我运行main.py,但没有任何输出。

1 个答案:

答案 0 :(得分:0)

关于exchanging data between processes的文档解释了您将队列作为参数移交给进程。你的代码在我的Mac上运行(我会称之为"偶然#34;因为它使用的是未记录的功能,这可能只是一个python版本的副作用),但不是在Windows上。

一个重要的事实是,以multiprocessing开始的进程没有共享内存空间(与线程不同,它们共享内存)。共享对象的机制是pipes, queues和通过shared memory or server processes创建的对象。

那就是说:我会在你的代码中改进一些东西:

  • 分成三个模块对我来说没有意义,尤其是p_1.pyp_2.py
  • 当一个类似于queue_run的正常功能也可以做到这一点时,你不清楚为什么你做了一个课test

这是你的例子,压缩成一个文件。我离开了课堂,所以你可以很容易地看到我改变了什么:

import multiprocessing
import time


def test(queue):
    var = ['a', 'b', 'c', 'd']
    for v in var:
        queue_put(queue, 'something : ' + v)
        time.sleep(0.8)


def queue_put(queue, something):
    queue.put(something)

class queue_run(multiprocessing.Process):
    def __init__(self, q):
        multiprocessing.Process.__init__(self)
        self.queue = q

    def run(self):
        print "started"
        while True:
            try:
                data = self.queue.get(timeout=1)
                print "got from queue: ", data
            except:
                print "timed out"
                break

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    process_1 = multiprocessing.Process(target=test, args=(queue,))
    process_2 = queue_run(queue)
    process_1.start()
    process_2.start()
    process_1.join()
    process_2.join()

P.S。您可能想要致电test制作人和queue_run消费者,以及如何在编程术语中调用它们

<强>更新

  

如果我将队列作为参数传递给所有子模块来解决上述问题,我需要修改所有文件,这是一个复杂的项目

当你在Windows上工作时(正如你在评论中所指出的那样),有一个重要的事实要知道:如果你创建一个新进程,它将是spawned:一个新的python解释器启动后,你的python模块被加载为新的,因此所有全局变量(如你的队列)都是用新实例重新启动的。这意味着无法与进程共享全局变量。

如果您希望继续使用多处理,唯一的方法是将它们传递给子模块。我无法想象你有超过50个子模块,所以一个好的编辑工作一小时应该可以解决问题。

另一种方法是使用threading:缺点是你只能使用一个cpu核心,好处是所有线程共享相同的内存空间。您唯一需要关心的是使用线程安全的数据结构,例如queue