Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多进程与主进程上的time.sleep挂起子进程_Python_Sleep_Python Multiprocessing - Fatal编程技术网

Python多进程与主进程上的time.sleep挂起子进程

Python多进程与主进程上的time.sleep挂起子进程,python,sleep,python-multiprocessing,Python,Sleep,Python Multiprocessing,我试图使用Python2.7中的多处理库,发现time.sleep()函数的行为有点令人不安。我需要控制一个定时关键硬件(在Raspberry PI上),我最初的目标是使用这个库来使用一个专用于此的过程。但是我发现让主要过程进入睡眠(time.sleep)也会让孩子进入睡眠!?!?这是正常的行为还是我错过了什么?下面是重现我的问题的代码示例: import time from multiprocessing import Process, Queue def child(q_display):

我试图使用Python2.7中的多处理库,发现time.sleep()函数的行为有点令人不安。我需要控制一个定时关键硬件(在Raspberry PI上),我最初的目标是使用这个库来使用一个专用于此的过程。但是我发现让主要过程进入睡眠(time.sleep)也会让孩子进入睡眠!?!?这是正常的行为还是我错过了什么?下面是重现我的问题的代码示例:

import time
from multiprocessing import Process, Queue

def child(q_display):

    c = 9999999

    while True:
        data = q_display.get()
        print data
        print c
        c = c - 1

if __name__ == '__main__':
    q_display = Queue()
    p = Process(target=child, args=(q_display,)).start()

    data = 1

    try:
        while True:
            q_display.put(data)
            data = data + 1
            print "MAIN ***********************************"
            time.sleep(1)

    except KeyboardInterrupt:
        print "Keyboard CTRL-C !!!"
输出如下:

MAIN ***********************************
1
9999999
MAIN ***********************************
2
9999998
MAIN ***********************************
3
9999997
MAIN ***********************************
4
9999996
MAIN ***********************************
5
9999995
MAIN ***********************************
6
9999994
但这正是我所期望的:

MAIN ***********************************
1
9999999
9999998
9999997
9999996
9999995
9999994
9999993
9999992
MAIN ***********************************
2
9999991
9999990
9999989
9999988
9999987
9999986
9999985
9999984
... etc

我做错了什么?

我认为问题在于,您正在将数据放入队列的循环中睡觉。因此,在主进程休眠之前,队列中只有一个值,因此子进程只能在阻塞之前读取一个值。

问题在于
queue.get()
阻塞,直到队列中有可用的项为止。通过将超时参数传递给
get()
函数,并捕获相应的错误(这需要从队列导入空的
),您可以继续在子进程中执行其他操作,即使主进程尚未发送任何内容。将子函数中的代码更改为:

while True:
    try:
        data = q_display.get(True, timeout=0.1)  # can raise Empty after 0.1 s
        print data
    except Empty:  # queue was empty, next time better
        pass
    print c
    c = c - 1
这似乎或多或少满足了您的需求:

MAIN ***********************************
MAIN ***********************************1
9999999
[...]
9999990
2
MAIN ***********************************
9999989
9999988
[...]
9999980
3
MAIN ***********************************
9999979
[...]
9999970
4
MAIN ***********************************
9999969
[...]
9999960
5
MAIN ***********************************
9999959
[...]
9999950
6
Keyboard CTRL-C !!!
9999949
[...]
9999943

请注意,主进程和子进程的打印输出可能会有点混乱,由于缓冲问题,它们不是监视事件确切时间的准确方法。

您需要使用Queue.Queue来捕获
队列。Empty
@padraickenningham在我从Queue import Empty执行
时对我有效。根据:“通常的队列。Empty和Queue。标准库队列模块的完全异常被引发以发出超时信号。”是的,对不起,我不是很清楚,我的意思是你需要使用队列库来捕获队列。Empty lib,使用Queue。Empty和OP的代码将出错。谢谢@Bas!我不再使用get_nowait()函数。我的子进程需要在多路复用模式下处理某些数码管的刷新,因此不需要等待0.1秒。我想留个口信。我需要在不到16毫秒的时间内刷新4位数字,这样就不会发生闪烁!再说一遍,我是Python新手,但我很喜欢它!:-)快到了,请看下面的答案!