为了尽快关闭应用程序,我可以从另一个线程中断 requests.post 调用并让它立即终止连接吗?
我玩过适配器,但到目前为止没有运气:
for ad in self.client.session.adapters.values():
ad.close()
为了尽快关闭应用程序,我可以从另一个线程中断 requests.post 调用并让它立即终止连接吗?
我玩过适配器,但到目前为止没有运气:
for ad in self.client.session.adapters.values():
ad.close()
正确的方法是使用消息传递到另一个线程。我们可以通过使用共享全局变量来做一个穷人版本。例如,您可以尝试运行此脚本:
#!/usr/bin/env python
# A test script to verify that you can abort streaming downloads of large
# files.
import threading
import time
import requests
stop_download = False
def download(url):
r = requests.get(url, stream=True)
data = ''
content_gen = r.iter_content()
while (stop_download == False):
try:
data = r.iter_content(1024)
except StopIteration:
break
if (stop_download == True):
print 'Killed from other thread!'
r.close()
if __name__ == '__main__':
t = threading.Thread(target=download,
args=('http://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/9.1/FreeBSD-9.1-RELEASE-amd64-dvd1.iso',)
).start()
time.sleep(5)
stop_download = True
time.sleep(5) # Just to make sure you believe that the message actually stopped the other thread.
在生产中执行此操作时,特别是如果您没有 GIL 的保护,您将需要在消息传递状态周围更加小心,以避免尴尬的多线程错误。我把它留给实施者。
我找到了一种方法,这里是如何中断连接
def close():
time.sleep(5)
r.raw._fp.close()
t = threading.Thread(target=close).start()
print "getting"
s = requests.Session()
r = s.get("http://download.thinkbroadband.com/1GB.zip", stream = True)
for line in r.iter_content(1024):
log.debug("got it: %s", len(line))
print "done"
然而这是一个 hack,我不喜欢它,私人成员将来可以改变,我回到 urllib2
因此,如果您从交互式 shell 执行以下操作,您会发现关闭适配器似乎并没有达到您想要的效果。
import requests
s = requests.session()
s.close()
s.get('http://httpbin.org/get')
<Response [200]>
for _, adapter in s.adapters.items():
adapter.close()
s.get('http://httpbin.org/get')
<Response [200]>
s.get('https://httpbin.org/get')
<Response [200]>
这看起来可能是请求中的错误,但总的来说,关闭适配器应该会阻止您发出进一步的请求,但我不完全确定它会中断当前正在运行的请求。
查看 HTTPAdapter(为标准'http://'
和'https://'
适配器提供支持),对其调用 close 将调用clear
底层 urrllib3 PoolManager。从 urllib3 的该方法的文档中,您可以看到:
This will not affect in-flight connections, but they will not be
re-used after completion.
因此,从本质上讲,您会看到您无法影响尚未完成的连接。