簡體   English   中英

用request.get掛起的多處理

[英]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 問題可能與猴子修補有關,因為我將requeststimemultiprocessing一起使用? 任何建議或意見,將不勝感激。 謝謝!

我在用:

  • 的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM