繁体   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