尝试了解python模块之间的多处理和队列

时间:2018-07-25 16:46:53

标签: python module queue multiprocessing

我试图了解多处理。我的实际应用是在pyqt5 GUI上实时显示日志消息,但是我在使用队列时遇到了一些问题,因此我编写了一个简单的程序对其进行测试。

我看到的问题是我无法跨python模块和跨进程向Queue添加元素。这是我的代码和输出以及预期的输出。

用于全局变量的配置文件:

# cfg.py
# Using a config file to import my globals across modules

#import queue
import multiprocessing

# q = queue.Queue()
q = multiprocessing.Queue()

主模块:

# mod1.py

import cfg
import mod2
import multiprocessing

def testq():
    global q
    print("q has {} elements".format(cfg.q.qsize()))

if __name__ == '__main__':
    testq()
    p = multiprocessing.Process(target=mod2.add_to_q)
    p.start()
    p.join()
    testq()
    mod2.pullfromq()
    testq()

辅助模块:

# mod2.py

import cfg

def add_to_q():
    cfg.q.put("Hello")
    cfg.q.put("World!")
    print("qsize in add_to_q is {}".format(cfg.q.qsize()))


def pullfromq():
    if not cfg.q.empty():
        msg = cfg.q.get()
        print(msg)

这是我实际从中得到的输出:

q has 0 elements
qsize in add_to_q is 2
q has 0 elements
q has 0 elements

vs我期望得到的输出:

q has 0 elements
qsize in add_to_q is 2
q has 2 elements
Hello
q has 1 elements

到目前为止,我已经尝试同时使用multiprocessing.Queuequeue.Queue。无论是否使用Process.join(),我也对此进行了测试。

如果在不使用multiprocessing的情况下运行相同的程序,则会得到上面显示的预期输出。

我在这里做什么错了?

编辑:

Process.run()给了我预期的输出,但是它在运行时也会阻塞主进程,这不是我想要的。

我的理解是Process.run()在调用过程(在我的情况下是主过程)的上下文中运行创建的过程,这意味着它与调用同一函数的主过程没有什么不同。

我仍然不明白为什么我的队列行为无法按预期进行

1 个答案:

答案 0 :(得分:1)

我已经找到了问题的根源,并将在此处进行记录以备将来搜索,但我仍然想知道是否存在在模块之间创建全局队列的标准解决方案,因此我将接受其他任何解决方案答案/评论。

将以下内容添加到cfg.py文件时,我发现了问题。

print("cfg.py is running in process {}".format(multiprocessing.current_process()))

这给了我以下输出:

cfg.py is running in process <_MainProcess(MainProcess, started)>
cfg.py is running in process <_MainProcess(Process-1, started)>
cfg.py is running in process <_MainProcess(Process-2, started)>

看来我正在为我创建的每个进程创建单独的Queue对象,这肯定可以解释为什么它们未按预期进行交互。

This question上有一条评论,指出

  

共享队列需要起源于主进程,然后再传递给其所有子进程。

所有这些,我仍然想知道是否存在一种有效的方法来在模块之间共享全局队列,而不必在方法之间传递它。