2017-09-09 18 views
1

リストをpythonキューに保存したい。リスト構造を単一のキューアイテムとして格納するのではなく、リストの各要素を1つずつキューに追加しようとしていると考えました。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のですか?ハァッ?

第2の混乱していることは、私のQueueオブジェクトには関数 "task_done"がないということです。これはドキュメントでは間違いなく存在します。

そして、主な混乱することは、なぜ私が置くことができない、これのように置くことができないのですか?これは私が作業しているはるかに大きなプロジェクトでは恐ろしく悪いです。これは、私が間違っていることを理解するための単なるテストスクリプトです。

+1

'L'は単純に' int'データ型ではなく、 'long'データ型であることを示しています。 – Antimony

+0

答えはありませんが、代わりにmanager.list()構造体を試してみてください。通常のリストのように機能しますが、共有データ構造です – koampapapa

答えて

1

このようなエラーが発生するたびに、キューをメモリにリフレッシュさせるためにクイックスリープを追加する必要があります。 python multiprocessingドキュメントはこれをほのめかしているように見える:子プロセスが キューにアイテムを入れている(と、それは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) 

です。

関連する問題