![](/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.