添加,删除,重新添加到python队列的意外行为

时间:2017-09-09 00:08:22

标签: python queue multiprocessing

我想在python队列中存储一个列表。我没有将列表结构存储为单个队列项,而是试图将列表中的每个元素逐个添加到队列中。

from multiprocessing import Process,Queue;
import time;
import sys;
def something1(q):
    q.put("hello");
    time.sleep(2);
    q.put("hello4");

def something2(q):
    q.put("hello2");
    time.sleep(1);
    q.put("hello3");


def run():
    queue = Queue();
    t1=Process(target=something1,args=(queue,));
    t1.start();
    t2=Process(target=something2,args=(queue,));
    t2.start();
    time.sleep(3);
    #queue.task_done();
    lol = [];
    while(queue.qsize() !=0):
        lol.append(queue.get(False));

    for l in lol:
        print("inside lol",l);
        queue.put(l);
    print("Queue size",queue.qsize());
    sys.stdout.flush();
    while(queue.qsize() !=0):
        print("inside queue",queue.get(False));
run();

我认为测试代码不言而喻......我只是想从队列中“获取”(这真的是一个流行音乐),然后在做我正在做的事情的最后我想重新将整个列表添加到队列中,以便其他进程可以使用该结构。

人们会期待:

('inside lol', 'hello')
('inside lol', 'hello2')
('inside lol', 'hello3')
('inside lol', 'hello4')
('Queue size', 4)
('inside queue', 'hello')
('inside queue', 'hello2')
('inside queue', 'hello3')
('inside queue', 'hello4')

但我得到了:

('inside lol', 'hello')
('inside lol', 'hello2')
('inside lol', 'hello3')
('inside lol', 'hello4')
('Queue size', 4L)
Traceback (most recent call last):
  File "mpTest.py", line 34, in <module>
    run();
  File "mpTest.py", line 33, in run
    print("inside queue",queue.get(False));
  File "/usr/lib/python2.7/multiprocessing/queues.py", line 134, in get
    raise Empty
Queue.Empty

队列大小是4L?咦?

第二个令人困惑的事情是我的Queue对象没有函数“task_done”,这是荒谬的,因为在文档中肯定存在。

主要令人困惑的是,为什么我不能这样放,得,像这样?这对于我正在研究的更大的项目来说是非常糟糕的,即这只是一个简单的测试脚本,可以帮助我理解我做错了什么。

1 个答案:

答案 0 :(得分:1)

每次遇到这样的错误时,都需要添加一个快速睡眠以让队列在内存中刷新。 python multiprocessing文档似乎暗示了这一点:

  

警告如上所述,如果子进程已将项目放在a上   然后,队列(并且它没有使用JoinableQueue.cancel_join_thread)   在所有缓冲项都存在之前,该进程不会终止   冲到管道上。这意味着如果您尝试加入该流程   你可能会陷入僵局,除非你确定所有的项目都有   被放在队列上已被消耗。同样,如果孩子   进程是非守护进程,然后父进程可能会在退出时挂起   它试图加入所有非守护儿童。

所以,你的代码运行正常:

from multiprocessing import Process,Queue;
import time;
import sys;
def something1(q):
    q.put("hello");
    time.sleep(2);
    q.put("hello4");

def something2(q):
    q.put("hello2");
    time.sleep(1);
    q.put("hello3");


def run():
    queue = Queue();
    t1=Process(target=something1,args=(queue,));
    t1.start();
    t2=Process(target=something2,args=(queue,));
    t2.start();
    time.sleep(3);
    #queue.task_done();
    lol = [];
    while(queue.qsize() !=0):
        lol.append(queue.get(False));

    for l in lol:
        print("inside lol",l);
        queue.put(l);
    print("Queue size",queue.qsize());
    sys.stdout.flush();
    time.sleep(0.1) # added by me
    while(queue.qsize() !=0):
        print("inside queue",queue.get(False));
run();

注意关键行是

time.sleep(0.1)

再次从队列中出来。