2015-05-26 170 views
3

以下是我正在运行的代码片段,它使用多处理并行地触发HTTP请求。在控制台上运行后,它将挂起“requests.get(url)”,既不继续也不抛出错误。Python:多处理和请求

def echo_100(q): 
    ... 
    print "before" 
    r = requests.get(url) 
    print "after" 
    ... 
    q.put(r) 

q = multiprocessing.Queue() 
p = multiprocessing.Process(target=echo_100,args=(q)) 
p.start() 
p.join() 
resp = q.get() 
+0

如果按顺序执行,'requests.get'是否返回URI? –

+0

您是否正在清理队列(即从某处发出q.get())? –

+0

requests.get需要第二个参数auth =('user','pass'),你确定你不需要它吗?此外,函数本身是否也能工作,即requests.get问题还是多处理问题? –

回答

0

如果你不清理队列,我的意思是不要把物品从队列中,该过程将在一段时间后挂起。多处理队列由Linux平台上未命名的FIFO(管道)支持。管道的最大尺寸限制。这意味着,如果一个进程写入管道而没有其他进程正在从管道读取数据,一段时间后,写入进程将挂起,同时尝试将更多数据放入管道(它可能挂在内部的写入系统调用中)。

我怀疑,您没有从队列中获取项目,因此队列在一段时间后变满,导致后续的子进程停滞。

现在,如果子进程挂起,那么如果父进程试图加入(p.join())子进程(在内部它将调用waitpid来加入子进程),它也可能挂起。

0

我有一个项目完全相同的问题。我发现在我的所有模块中删除import ipdb调用可解决此问题。我不确定为什么导入导致这个问题,但消除那些导入完全解决了它。只要单独导入就会导致问题,我甚至没有使用ipdb软件包中的任何东西。

UPDATE:这发生在两个Python的2.7.10和3.5.0,只有当我输入ipdb;如果您导入pdb,一切正常。我已经发布了一个相关的问题,问为什么会发生这种情况here

希望这可以解决您的问题。

2

在Mac OS上,从操作系统读取代理设置似乎存在一些错误。我不知道确切的细节,但有时会导致请求在使用多处理时挂起。你可以尝试通过完全禁用操作系统代理来绕过这个问题,像这样:

session = requests.Session() 
session.trust_env = False # Don't read proxy settings from OS 
r = session.get(url) 

为我修好了。