Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.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 JoinableQueue join()方法即使在任务完成()后仍阻止主线程_Python_Multiprocessing - Fatal编程技术网

Python JoinableQueue join()方法即使在任务完成()后仍阻止主线程

Python JoinableQueue join()方法即使在任务完成()后仍阻止主线程,python,multiprocessing,Python,Multiprocessing,在下面的代码中,如果我输入daemon=True,消费者将在读取所有队列条目之前退出。如果使用者是非守护进程,则主线程总是被阻塞,即使在所有条目的任务完成()之后也是如此 from multiprocessing import Process, JoinableQueue import time def consumer(queue): while True: final = queue.get() print (final) que

在下面的代码中,如果我输入
daemon=True
,消费者将在读取所有队列条目之前退出。如果使用者是非守护进程,则主线程总是被阻塞,即使在所有条目的
任务完成()之后也是如此

from multiprocessing import Process, JoinableQueue

import time


def consumer(queue):
    while True:
        final = queue.get()
        print (final)
        queue.task_done()


def producer1(queue):
    for i in "QWERTYUIOPASDFGHJKLZXCVBNM":
        queue.put(i)

if __name__ == "__main__":

    queue = JoinableQueue(maxsize=100)
    p1 = Process(target=consumer, args=((queue),))
    p2 = Process(target=producer1, args=((queue),))
    #p1.daemon = True
    p1.start()
    p2.start()
    print(p1.is_alive())
    print (p2.is_alive())
    for i in range(1, 10):
        queue.put(i)
        time.sleep(0.01)
    queue.join()

让我们看看我相信这里发生了什么:

  • 这两个进程都正在启动
  • 使用者
    进程启动其循环并阻塞,直到从队列接收到值
  • producer1
    进程向队列提供26次字母,而主进程向队列提供9次数字。字母或数字的输入顺序不能保证——一个数字很可能在一个字母之前出现
  • producer1
    和主进程都完成数据馈送时,队列被加入。这里没有问题,可以加入队列,因为所有缓冲数据都已使用,并且在每次读取后都调用了
    task\u done()
  • 使用者
    进程仍在运行,但会被阻止,直到显示更多要使用的数据
  • 看看你的代码,我相信你混淆了加入进程和加入队列的概念。这里您最希望的是加入进程,您可能根本不需要可加入的队列

    #!/usr/bin/env python3
    
    from multiprocessing import Process, Queue
    
    import time
    
    def consumer(queue):
        for final in iter(queue.get, 'STOP'):
            print(final)
    
    def producer1(queue):
        for i in "QWERTYUIOPASDFGHJKLZXCVBNM":
            queue.put(i)
    
    if __name__ == "__main__":
        queue = Queue(maxsize=100)
        p1 = Process(target=consumer, args=((queue),))
        p2 = Process(target=producer1, args=((queue),))
        p1.start()
        p2.start()
        print(p1.is_alive())
        print(p2.is_alive())
        for i in range(1, 10):
            queue.put(i)
            time.sleep(0.01)
        queue.put('STOP')
        p1.join()
        p2.join()
    
    此外,您的
    producer1
    在输入所有字母后会自动退出,但您需要一种方法,在没有更多数据可供处理时,告诉您的
    消费者
    流程退出。你可以通过发送一个哨兵来做到这一点,在这里我选择了字符串
    'STOP'
    ,但它可以是任何东西


    事实上,这段代码不是很好,因为
    'STOP'
    哨兵可以在一些信件之前接收,因此既会导致一些信件无法处理,也会导致死锁,因为即使队列中仍然包含一些数据,进程仍在尝试加入。但这是一个不同的问题。

    让我们看看——我相信这里发生了什么:

  • 这两个进程都正在启动
  • 使用者
    进程启动其循环并阻塞,直到从队列接收到值
  • producer1
    进程向队列提供26次字母,而主进程向队列提供9次数字。字母或数字的输入顺序不能保证——一个数字很可能在一个字母之前出现
  • producer1
    和主进程都完成数据馈送时,队列被加入。这里没有问题,可以加入队列,因为所有缓冲数据都已使用,并且在每次读取后都调用了
    task\u done()
  • 使用者
    进程仍在运行,但会被阻止,直到显示更多要使用的数据
  • 看看你的代码,我相信你混淆了加入进程和加入队列的概念。这里您最希望的是加入进程,您可能根本不需要可加入的队列

    #!/usr/bin/env python3
    
    from multiprocessing import Process, Queue
    
    import time
    
    def consumer(queue):
        for final in iter(queue.get, 'STOP'):
            print(final)
    
    def producer1(queue):
        for i in "QWERTYUIOPASDFGHJKLZXCVBNM":
            queue.put(i)
    
    if __name__ == "__main__":
        queue = Queue(maxsize=100)
        p1 = Process(target=consumer, args=((queue),))
        p2 = Process(target=producer1, args=((queue),))
        p1.start()
        p2.start()
        print(p1.is_alive())
        print(p2.is_alive())
        for i in range(1, 10):
            queue.put(i)
            time.sleep(0.01)
        queue.put('STOP')
        p1.join()
        p2.join()
    
    此外,您的
    producer1
    在输入所有字母后会自动退出,但您需要一种方法,在没有更多数据可供处理时,告诉您的
    消费者
    流程退出。你可以通过发送一个哨兵来做到这一点,在这里我选择了字符串
    'STOP'
    ,但它可以是任何东西

    事实上,这段代码不是很好,因为
    'STOP'
    哨兵可以在一些信件之前接收,因此既会导致一些信件无法处理,也会导致死锁,因为即使队列中仍然包含一些数据,进程仍在尝试加入。但这是另一个问题