我正在寻找中止/取消 Python 线程中的 HTTP 请求。我必须坚持使用线程。我无法使用 asyncio 或标准库之外的任何内容。
此代码适用于套接字:
"""Demo for Canceling IO by Closing the Socket
Works!
"""
import socket
import time
from concurrent import futures
start_time = time.time()
sock = socket.socket()
def read():
"Read data with 10 second delay."
sock.connect(('httpbin.org', 80))
sock.sendall(b'GET /delay/10 HTTP/1.0\r\n\r\n')
while True:
data = sock.recv(1024)
if not data:
break
print(data.decode(), end='')
with futures.ThreadPoolExecutor() as pool:
future = pool.submit(read)
futures.wait([future], timeout=5)
sock.close() # <-- Interrupt sock.recv(1024) in Thread:read().
end_time = time.time()
print(f'Duration: {end_time - start_time:.3f}')
# Duration is ~5s as expected.
在主线程中关闭套接字用于中断执行器池线程中的recv()。HTTP 请求应该需要 10 秒,但我们只等待 5 秒,然后关闭套接字(有效地取消 HTTP 请求/响应)。
现在我尝试使用 http.client:
"""Demo for Canceling IO in Threads with HTTP Client
Doesn't work!
"""
import time
from concurrent import futures
from http.client import HTTPConnection
def get(con, url):
con.request('GET', url)
response = con.getresponse()
return response
start_time = time.time()
with futures.ThreadPoolExecutor() as executor:
con = HTTPConnection('httpbin.org')
future = executor.submit(get, con, '/delay/10')
done, not_done = futures.wait([future], timeout=5)
con.sock.close()
end_time = time.time()
print(f'Duration: {end_time - start_time:.3f}')
# Duration is ~10s unfortunately.
不幸的是,这里的总持续时间约为 10 秒。关闭套接字不会中断客户端中的recv_into()。
看来我做出了一些错误的假设。如何从单独的线程中断 http 客户端中使用的套接字?
DIEA
相关分类