7

Mã sau đây, không in "here". Vấn đề là gì? Tôi đã thử nghiệm trên cả hai máy của mình (windows 7, Ubuntu 12.10) và http://www.compileonline.com/execute_python_online.php Nó không in "here" trong mọi trường hợp.Tập lệnh sử dụng mô-đun đa xử lý không chấm dứt

from multiprocessing import Queue, Process 


def runLang(que): 
    print "start" 
    myDict=dict() 
    for i in xrange(10000): 
     myDict[i]=i 
    que.put(myDict) 
    print "finish" 


def run(fileToAnalyze): 
    que=Queue() 
    processList=[] 
    dicList=[] 
    langs= ["chi","eng"] 
    for lang in langs: 
     p=Process(target=runLang,args=(que,)) 
     processList.append(p) 
     p.start() 

    for p1 in processList: 
     p1.join() 

    print "here" 

    for _ in xrange(len(langs)): 
     item=que.get() 
     print item 
     dicList.append(item) 

if __name__=="__main__": 
    processList = [] 
    for fileToAnalyse in ["abc.txt","def.txt"]: 
     p=Process(target=run,args=(fileToAnalyse,)) 
     processList.append(p) 
     p.start() 
    for p1 in processList: 
     p1.join() 

Trả lời

13

Điều này là do khi bạn put nhiều mục vào một multiprocessing.Queue, cuối cùng họ được đệm trong bộ nhớ, một khi tiềm ẩn Pipe đầy. Bộ đệm sẽ không bị xóa cho đến khi có gì đó bắt đầu đọc từ đầu kia của Queue, cho phép Pipe chấp nhận nhiều dữ liệu hơn. Một Process không thể chấm dứt cho đến khi bộ đệm cho tất cả các trường hợp Queue của nó đã được hoàn toàn đỏ bừng đến lớp cơ bản Pipe. Ý nghĩa của điều này là nếu bạn cố gắng join một quá trình mà không cần phải gọi quá trình/thread khác get trên Queue, bạn có thể bế tắc. Đây là mentioned in the docs:

Cảnh báo

Như đã đề cập ở trên, nếu một quá trình con đã đặt mục trên một hàng đợi (và nó đã không được sử dụng JoinableQueue.cancel_join_thread), sau đó là quá trình sẽ không chấm dứt cho đến khi tất cả các mục đệm đã được xả lên ống .

Điều này có nghĩa là nếu bạn cố gắng tham gia quá trình đó, bạn có thể bị bế tắc trừ khi bạn chắc chắn rằng tất cả các mục đã được đưa vào hàng đợi đã được sử dụng. Tương tự như vậy, nếu quá trình con là không daemonemon thì quá trình cha mẹ có thể treo khi thoát khi nó cố gắng tham gia tất cả các trẻ em không daemonemon của nó.

Lưu ý rằng hàng đợi được tạo bằng trình quản lý không có vấn đề này.

Bạn có thể khắc phục vấn đề bằng cách không gọi join cho đến khi bạn rỗng Queue trong các phụ huynh:

for _ in xrange(len(langs)): 
    item = que.get() 
    print(item) 
    dicList.append(item) 

# join after emptying the queue. 
for p in processList: 
    p.join() 

print("here") 
Các vấn đề liên quan