![](/img/trans.png)
[英]Requests.get in multiprocessing pool blocked by a Matplotlib figure?
[英]Multiprocessing hanging with requests.get
我一直在處理一些非常簡單的代碼,但是這種行為非常奇怪。 我正在嘗試使用request.get將requests.get
發送到網頁,但是如果該請求花費的時間超過幾秒鍾,那么我想終止該過程。 我下面從接受答案的響應這里 ,但改變函數體包含了request
。 我的代碼如下:
import multiprocessing as mp, requests
def get_page(_r):
_rs = requests.get('https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas').text
_r.put(_rs)
q = mp.Queue()
p = mp.Process(target=get_page, args=(q,))
p.start()
time.sleep(3)
p.terminate()
p.join()
try:
result = q.get(False)
print(result)
except:
print('failed')
上面的代碼在運行時會掛起。 但是,當我跑步時
requests.get('https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas').text
獨立地,在兩秒鍾內返回響應。 因此,主代碼應該打印頁面的HTML,但是它只是停滯了。 奇怪的是,當我在get_page
放入無限循環時:
def get_page(_r):
while True:
pass
_r.put('You will not see this')
該過程確實在三秒鍾后終止。 因此,我確定行為與requests
。 怎么會這樣 我在這里發現了類似的問題,但是我沒有使用async
。 問題可能與猴子修補有關,因為我將requests
與time
和multiprocessing
一起使用? 任何建議或意見,將不勝感激。 謝謝!
我在用:
的Python 3.7.0
requests
2.21.0
編輯:@Hitobat指出,可以將params timeout
用於requests
。 的確確實有效,但是,與其他原因有關的multiprocessing
requests
失敗的原因,我將不勝感激。
我已轉載了您的情況,並且我不得不駁斥上述假設“我確定行為與請求有關” 。
requests.get(...)
返回預期的響應。
讓我們看一下調試過程如何進行:
import multiprocessing as mp, requests
import time
def get_page(_r):
_rs = requests.get('https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas').text
print('--- response header', _rs[:17])
_r.put(_rs)
q = mp.Queue()
p = mp.Process(target=get_page, args=(q,))
p.start()
time.sleep(3)
p.terminate()
p.join()
try:
print('--- get data from queue of size', q.qsize())
result = q.get(False)
print(result)
except Exception as ex:
print('failed', str(ex))
輸出:
--- response header
<!DOCTYPE html>
--- get data from queue of size 1
正如我們看到的那樣,響應在那里,進程甚至可以try
塊語句,但是當嘗試從隊列中提取數據時,它會掛起/停止在q.get()
語句上。 因此,我們可以得出結論,隊列很可能已損壞。 而且在multiprocessing
庫文檔中( Pipes and Queues
部分),我們有相應的警告:
警告
如果在嘗試使用隊列時使用
Process.terminate()
或os.kill()將其殺死,則隊列中的數據可能會損壞。 這可能會導致其他進程稍后嘗試使用隊列時獲得異常。
看起來是這種情況。
我們如何處理這個問題?
已知的解決方法是使用mp.Manager().Queue()
(具有中間代理級別)而不是mp.Queue
:
...
q = mp.Manager().Queue()
p = mp.Process(target=get_page, args=(q,))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.