繁体   English   中英

使用 python 如何使用队列在子进程和主进程之间传递数据?

[英]Using python how can I pass data between child and main processes with Queue?

期望的目标

我正在做一个项目。 我想做的是每天运行一个 python 文件,获取和处理数据。 在处理所述数据的过程中,如果某些参数为真,则将数据发送到另一个子进程进行进一步处理。 在“进一步”处理该数据时,我希望第一个进程继续(可能在睡眠后)以获取和处理新数据(在某个指定时间)。

我想整天运行这个脚本; 因此,我尝试将 while 循环与 time.sleep 一起使用。 我遇到了 Queue 模块,并认为这可能是我可以根据设计在进程之间传递数据的一种方式,这些进程永远不会完成。

关注点

-进程永远不会完成是一个问题吗?

- class 方法永远不会返回/完成是否有问题?

这会导致堆栈溢出吗? (我希望这会整天运行)。 我想我不必打印,而只是对数据结构进行操作,也许保存到磁盘。

选择

我喜欢整个程序是一个脚本/类的想法。 然而,这不是正确的编码礼仪吗? 拥有几个不同的脚本并保存到数据库/pickle并从数据库/pickle加载会更合适吗?

什么有效

如果我在下面的示例中将多处理换成线程,我会收到所需的 output。 但是在我的实际项目中,线程不起作用(这是一个不同的故事),但多处理可以。 因此,我想在这里提问,以扩大我对正在发生的事情的理解,以便在项目中获得我想要的结果。

试过

-尝试将多处理切换为线程,这似乎给了我想要的结果,但想了解为什么多处理没有给出相同的 output。

- 尝试使用 Queue() 或 LifoQueue() - 尝试从另一个子子进程而不是主脚本运行和打印 Queue.get() -Tried.join() 所有任务

所需 output

我希望在子进程中更改颜色并从主脚本/父进程传递给队列,我希望使用 Queue.get() 检索新颜色并打印。

例子

import multiprocessing
import threading
import time

class MyClass:
    def __init__(self):
        self.color = 'gray'
    
    def task_blue(self,q):
        print('sleeping 5..')
        time.sleep(5)
        while True:     
            time.sleep(1)
            self.color = 'blue'
            q.put([self.color])

    def task_red(self,q):
        print('sleeping 5..')
        time.sleep(5)
        while True:
            time.sleep(3)
            self.color = 'red'
            q.put([self.color])
        
    def printer(self,q):
        while True:
            time.sleep(.1)
            if q.empty():
                print('<empty>')
            else:
    
                print(q.get())

from queue import LifoQueue, Queue        
q = LifoQueue()
my_class = MyClass()

p1 = multiprocessing.Process(target=my_class.task_blue,args=(q,),name='BLUE')
p2 = multiprocessing.Process(target=my_class.task_red,args=(q,),name='RED')
# p3 = multiprocessing.Process(target=my_class.printer,args=(q,),name='PRINTER')

tasks = []
tasks.append(p1)
tasks.append(p2)
# tasks.append(p3)

for task in tasks:
    task.start()

while True:
    time.sleep(.2)
    if q.empty():
        print(['empty'])
    else:
        print(q.get())

output

输出

过程永远不会完成是一个问题吗?

一个进程永远运行是可以的。

class 方法永远不会返回/完成是否有问题?

不。如果你希望你的程序永远运行,就会有一段代码不会返回。 如果此代码区域位于方法内部,则可以。

我喜欢整个程序是一个脚本/类的想法

你可以通过很多方式做到这一点。 这里没有正确答案,尤其是没有其他要求。

尝试使用 Queue() 或 LifoQueue() - 尝试从另一个子子进程而不是主脚本运行和打印 Queue.get() -Tried.join() 所有任务

当使用multiprocessing package 时,您应该使用多处理 package 中的Queue class 例如queue = multiprocessing.Queue() 此处的文档: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM