鍍金池/ 問答/Java  Python/ Python多進程不能將信息放入隊列

Python多進程不能將信息放入隊列

1.Python多進程不能將信息放入隊列
2.代碼:

from urllib import request
from bs4 import BeautifulSoup
from multiprocessing import Manager
from multiprocessing import Pool
import os

def hand_url(url,name,queue):
    room_message = {} #存放我需要的信息

    print(name,os.getpid())
    one_roomlist=[]
    req=request.Request(url)
    req.add_header('User-Agent','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36')
    with request.urlopen(req)as f:
        data = f.read().decode()
    soup = BeautifulSoup(data, 'html.parser')
    clear_1 = soup.find_all(class_="table_type_7 responsive_table full_width t_align_l")
    clear_1 = clear_1[0].tbody.contents
    for i in clear_1:
        if i != '\n':
            message_small = []
            for x in i.strings:
                if x != '\n':
                    message_small.append(x)


            one_roomlist.append(message_small)

        room_message[name] = one_roomlist

                  #前半部分為爬去網頁信息和篩選內容
    print(room_message)
    queue.put(room_message)     #程序在這里卡住了,room_message為一個字典
    print('ok')



if __name__ == '__main__':
    queue=Manager().Queue()
    pool = Pool(4)
    pool.apply_async(hand_url,('http://202.115.129.139:81/trainingroomnote?roomid=91','A405',queue))
    pool.close()
    pool.join()
    print(queue.get())

3.問題截圖

clipboard.png

4.我自己嘗試把print(room_message)得到的內容直接復制添加到隊列里面是可以的,但是一旦改成queue.put(room_message)程序是卡在這里的

回答
編輯回答
舊酒館

道友 你首先要明白問題所在,到底是什么原因。
打個斷點,進去到queue隊列里的代碼看看。看看queue里面的代碼是卡在了哪一步,報錯了嗎?如果報錯了,是什么錯誤。
有時候,代碼會捕獲異常,讓你無法直接判斷錯誤所在。

回到這個問題,程序卡住了,是不是隊列滿了?是不是有異常未捕獲? 是不是達到了競態(tài)條件?是不是發(fā)生了死鎖?(是的是的 就是你)

這個根本原因在于 你的隊列queue其實是共享變量,多線程不安全。線程池里對該隊列的操作達到了競態(tài)條件,所以一直等待對象鎖的釋放(同步阻塞ing)
把程序好好改一下吧,做個同步,給隊列加個鎖就行了。
好好看一下多線程的內存模型,消費者生產者模式 就行

2018年7月17日 22:50