要儘快關閉應用程序,我可以中斷來自另一個線程的requests.post調用並立即終止連接嗎?從另一個線程關閉「Python請求」連接
我打適配器,但至今沒有運氣:
for ad in self.client.session.adapters.values():
ad.close()
要儘快關閉應用程序,我可以中斷來自另一個線程的requests.post調用並立即終止連接嗎?從另一個線程關閉「Python請求」連接
我打適配器,但至今沒有運氣:
for ad in self.client.session.adapters.values():
ad.close()
因此,如果您從交互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將調用底層urrllib3 PoolManager上的clear
。從這個方法的urllib3的文檔,你看到了:
This will not affect in-flight connections, but they will not be
re-used after completion.
所以在本質上,你看,你無法影響尚未完成的連接。
我找到了一種方法,在這裏是如何中斷連接
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"
但是這是一個黑客,我不喜歡它,私有成員可以,我回國的urllib2
改變未來正確的做法是將消息傳遞到另一個線程。我們可以通過使用一個共享的全局變量來做一個糟糕的版本。舉個例子,你可以嘗試運行此腳本:
#!/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的保護,你會希望使用更謹慎周圍的消息傳遞狀態以避免尷尬的多線程錯誤。我要把它留給實現者。
此外,您可以使用非常小的內容大小來取得更好的控制權。而你的'content_gen = r.iter_content()'是不必要的;} – 2013-05-08 13:34:23
'iter_content()'返回一個迭代器(或者生成器),所以你應該像'content_gen = r.iter_content(1024)'' '下(content_gen)'。 – 2013-10-09 05:12:08
@Lukasa,你能告訴我,當'r = requests.get(url,stream = True)'行被執行時,響應數據是否會全部下載到ram的某處?因爲我不確定何時'data = r.iter_content(1024)',1024字節的數據來自哪裏。我想知道如果是這樣的話,以後終止請求是沒有用的,因爲數據已經被下載(請求/響應結束)。 – Bin 2015-11-11 09:22:52
是的,不幸的是請求不是這樣設計的,我想小的http請求是主要目的。我使用它作爲桌面應用程序,客戶端必須讓其中斷。 – 2013-05-07 04:51:35
您可能會深入挖掘urllib3並強行關閉套接字,但urllib3位於httplib之上,我不知道這是否可能。如果你想要細粒度的控制,你可以使用原始套接字自己構造整個請求(並解析響應)。當用戶想要取消某件事情時,只需關閉套接字即可。雖然這是很多工作。 – 2013-05-07 13:26:40