Python urlopen/requests.get在导入模块中创建的线程中不工作
我对urlopen有问题 (和请求。get) 在我的程序中,如果我在一个线程内运行它(我也用Python urlopen/requests.get在导入模块中创建的线程中不工作,python,multithreading,python-requests,urllib2,urlopen,Python,Multithreading,Python Requests,Urllib2,Urlopen,我对urlopen有问题 (和请求。get) 在我的程序中,如果我在一个线程内运行它(我也用多处理进行了测试)[更新:一个由导入的模块创建的线程],它在程序结束之前不会运行 我所说的“不运行”是指甚至不启动:超时(这里是3秒)永远不会触发,并且没有与网站的连接 以下是我的简化代码: import threading,urllib2,time def dlfile(url): print 'Before request' r = urllib2.urlopen(url, timeout=
多处理
进行了测试)[更新:一个由导入的模块创建的线程],它在程序结束之前不会运行
我所说的“不运行”是指甚至不启动:超时(这里是3秒)永远不会触发,并且没有与网站的连接
以下是我的简化代码:
import threading,urllib2,time
def dlfile(url):
print 'Before request'
r = urllib2.urlopen(url, timeout=3)
print 'After request'
return r
def dlfiles(*urls):
threads = [threading.Thread(None, dlfile, None, (url,), {}) for url in urls]
map(lambda t:t.start(), threads)
def main():
dlfiles('http://google.com')
main()
time.sleep(10)
print 'End of program'
我的输出:
Before request
End of program
After request
不幸的是,我正在编写的代码工作正常(即“请求前/请求后/程序结束”),我还不能用简化的代码重现这个问题
我仍在尝试,但与此同时,我想知道是否有人遇到过这种奇怪的行为,以及是什么导致了这种行为。请注意,如果我不使用线程,一切都很好
谢谢你能提供的帮助,我有点迷路了,连互联网都不知道
更新
下面是如何重现这种行为
threadtest.py
import threading,urllib2,time
def log(a):print(a)
def dlfile(url):
log('Before request')
r = urllib2.urlopen(url, timeout=3)
log('After request')
return r
def dlfiles(*urls):
threads = [threading.Thread(None, dlfile, None, (url,), {}) for url in urls]
map(lambda t:t.start(), threads)
def main():
dlfiles('http://google.com')
main()
for i in range(5):
time.sleep(1)
log('Sleep')
log('End of program')
threadtest导入.py
import threading,urllib2,time
def log(a):print(a)
def dlfile(url):
log('Before request')
r = urllib2.urlopen(url, timeout=3)
log('After request')
return r
def dlfiles(*urls):
threads = [threading.Thread(None, dlfile, None, (url,), {}) for url in urls]
map(lambda t:t.start(), threads)
def main():
dlfiles('http://google.com')
main()
for i in range(5):
time.sleep(1)
log('Sleep')
log('End of program')
导入线程测试
然后输出将如下所示:
$ python threadtest.py
Before request
After request
Sleep
Sleep
Sleep
Sleep
Sleep
End of program
$ python threadtest-import.py
Before request
Sleep
Sleep
Sleep
Sleep
Sleep
End of program
After request
现在我发现了如何繁殖:这种行为正常吗?期待
我怎样才能摆脱它呢?也就是说,从导入的模块创建一个线程,该线程可以按预期加载urlopen。您的代码很好。预计单次发射
def main():
dlfiles('http://google.fr')
这里您正在传递单个url
threads = [threading.Thread(None, dlfile, None, (url,), {}) for url in urls]
列表理解将只产生一个线程,因为URL
中只有一个元素
尝试:
def main():
dlfiles('http://google.fr', 'http://google.com', 'http://google.gg')
感谢@user3351750的评论,我忘记发布解决方案了 问题是文件的结构。在threadtest-import.py中,我导入了threadtest,在导入模块的过程中,一些*(我不记得确切的机制)变成了阻塞。IIRC这与urllib中的re模块有关。 抱歉说不清楚 修复方法是将代码放入函数中导入的模块中。我想这是一个很好的做法 即,这样做:
import threadtest #do nothing except declarations
threadtest.run() #do the work
与此相反:
import threadtest #declarations + work
然后把密码
main()
for i in range(5):
time.sleep(1)
log('Sleep')
log('End of program')
在运行
功能中:
def run():
main()
for i in range(5):
time.sleep(1)
log('Sleep')
log('End of program')
这样,东西*就不再阻塞,一切正常。也许我不够清楚,但我在OP中编写的代码只是一个简化的代码,甚至不会重现错误。我的问题是,在我的实际程序中,所有urlopen调用(1个或多个)都将仅在程序退出后进行。从今天起,
threadtest import.py
脚本将给出正常结果“请求前/请求后/睡眠*5”。我不明白这里发生了什么……我面临着类似的问题。你能找出原因吗?有解决办法吗?
def main():
dlfiles('http://google.fr')