出现异常错误“线程 Thread-13 中的异常(很可能在解释器关闭期间引发)”
Got Exception Error “Exception in thread Thread-13 (most likely raised during interpreter shutdown)”
我写了一个简单的脚本,它使用线程从服务中检索数据。
__author__ = 'Igor'
import requests
import time
from multiprocessing.dummy import Pool as ThreadPool
ip_list = []
good_ip_list = []
bad_ip_list = []
progress = 0
with open('/tmp/ip.txt') as f:
ip_list = f.read().split()
def process_request(ip):
global progress
progress += 1
if progress % 10000 == 0:
print 'Processed ip:', progress, '...'
r = requests.get('http://*****/?ip='+ip, timeout=None)
if r.status_code == 200:
good_ip_list.append(ip)
elif r.status_code == 400:
bad_ip_list.append(ip)
else:
print 'Unknown http code received, aborting'
exit(1)
pool = ThreadPool(16)
try:
pool.map(process_request, ip_list)
except:
for name, ip_list in (('/tmp/out_good.txt', good_ip_list), ('/tmp/out_bad.txt', bad_ip_list)):
with open(name, 'w') as f:
for ip in ip_list:
print>>f, ip
但在处理了一些请求 (40k-50k) 之后,我收到:
线程 Thread-7 中的异常(很可能在解释器关闭期间引发):
追溯(最近一次通话):
进程已完成,退出代码为 0
试图更改服务设置:
<timeout>999</timeout>
<connectionlimit>600</connectionlimit>
<httpthreads>32</httpthreads>
<workerthreads>128</workerthreads>
但还是一样的错误。谁能帮帮我 - 怎么了?
这个:
good_ip_list = []
bad_ip_list = []
与 Python 多处理混合使用是不安全的。正确的方法是 return 每次调用 process_request
的元组(或其他东西),然后在最后将它们全部连接起来。从多个进程同时修改 progress
也不安全。我不确定你的错误是什么,但我敢打赌它是一些同步问题,它正在杀死整个 Python。
删除共享状态并重试。
感谢所有帮助我解决这个问题的人。重写了整个代码,现在可以完美运行了:
__author__ = 'kulakov'
import requests
import time
from multiprocessing.dummy import Pool as ThreadPool
ip_list = []
good_ip_list = []
bad_ip_list = []
with open('/tmp/ip.txt') as f:
ip_list = f.read().split()
s = requests.Session()
def process_request(ip):
r = s.get('http://*****/?ip='+ip, timeout=None)
if r.status_code == 200:
# good_ip_list.append(ip)
return (ip, True)
elif r.status_code == 400:
# bad_ip_list.append(ip)
return (ip, False)
else:
print 'Unknown http code received, aborting'
exit(1)
pool = ThreadPool(16)
for ip, isOk in pool.imap(process_request, ip_list):
if isOk:
good_ip_list.append(ip)
else:
bad_ip_list.append(ip)
pool.close()
pool.join()
for name, ip_list in (('/tmp/out_good.txt', good_ip_list), ('/tmp/out_bad.txt', bad_ip_list)):
with open(name, 'w') as f:
for ip in ip_list:
print>>f, ip
一些有用的新信息:
1) 在一个函数process_request
的不同线程中写数据真的是个坏主意,现在returns语句(true\false)和ip.
2) keep alive
默认情况下完全支持 requests
,但是如果你想使用它,你必须创建一个对象的实例 Session
,并应用 get
方法:
s = requests.Session()
r = s.get('http://*****/?ip='+ip, timeout=None)
我写了一个简单的脚本,它使用线程从服务中检索数据。
__author__ = 'Igor'
import requests
import time
from multiprocessing.dummy import Pool as ThreadPool
ip_list = []
good_ip_list = []
bad_ip_list = []
progress = 0
with open('/tmp/ip.txt') as f:
ip_list = f.read().split()
def process_request(ip):
global progress
progress += 1
if progress % 10000 == 0:
print 'Processed ip:', progress, '...'
r = requests.get('http://*****/?ip='+ip, timeout=None)
if r.status_code == 200:
good_ip_list.append(ip)
elif r.status_code == 400:
bad_ip_list.append(ip)
else:
print 'Unknown http code received, aborting'
exit(1)
pool = ThreadPool(16)
try:
pool.map(process_request, ip_list)
except:
for name, ip_list in (('/tmp/out_good.txt', good_ip_list), ('/tmp/out_bad.txt', bad_ip_list)):
with open(name, 'w') as f:
for ip in ip_list:
print>>f, ip
但在处理了一些请求 (40k-50k) 之后,我收到:
线程 Thread-7 中的异常(很可能在解释器关闭期间引发): 追溯(最近一次通话): 进程已完成,退出代码为 0
试图更改服务设置:
<timeout>999</timeout>
<connectionlimit>600</connectionlimit>
<httpthreads>32</httpthreads>
<workerthreads>128</workerthreads>
但还是一样的错误。谁能帮帮我 - 怎么了?
这个:
good_ip_list = []
bad_ip_list = []
与 Python 多处理混合使用是不安全的。正确的方法是 return 每次调用 process_request
的元组(或其他东西),然后在最后将它们全部连接起来。从多个进程同时修改 progress
也不安全。我不确定你的错误是什么,但我敢打赌它是一些同步问题,它正在杀死整个 Python。
删除共享状态并重试。
感谢所有帮助我解决这个问题的人。重写了整个代码,现在可以完美运行了:
__author__ = 'kulakov'
import requests
import time
from multiprocessing.dummy import Pool as ThreadPool
ip_list = []
good_ip_list = []
bad_ip_list = []
with open('/tmp/ip.txt') as f:
ip_list = f.read().split()
s = requests.Session()
def process_request(ip):
r = s.get('http://*****/?ip='+ip, timeout=None)
if r.status_code == 200:
# good_ip_list.append(ip)
return (ip, True)
elif r.status_code == 400:
# bad_ip_list.append(ip)
return (ip, False)
else:
print 'Unknown http code received, aborting'
exit(1)
pool = ThreadPool(16)
for ip, isOk in pool.imap(process_request, ip_list):
if isOk:
good_ip_list.append(ip)
else:
bad_ip_list.append(ip)
pool.close()
pool.join()
for name, ip_list in (('/tmp/out_good.txt', good_ip_list), ('/tmp/out_bad.txt', bad_ip_list)):
with open(name, 'w') as f:
for ip in ip_list:
print>>f, ip
一些有用的新信息:
1) 在一个函数process_request
的不同线程中写数据真的是个坏主意,现在returns语句(true\false)和ip.
2) keep alive
默认情况下完全支持 requests
,但是如果你想使用它,你必须创建一个对象的实例 Session
,并应用 get
方法:
s = requests.Session()
r = s.get('http://*****/?ip='+ip, timeout=None)