得到异常错误“Thread-13线程中的异常(最有可能在解释器关闭期间引发)”

时间:2015-03-13 08:17:35

标签: python multithreading exception

我写了一个简单的脚本,它使用线程从服务中检索数据。

    __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中的异常(很可能在解释器关闭期间引发): Traceback(最近一次调用最后一次): 处理以退出代码0结束

尝试更改服务设置:

        <timeout>999</timeout>
        <connectionlimit>600</connectionlimit>
        <httpthreads>32</httpthreads>
        <workerthreads>128</workerthreads>

但仍然是同样的错误。任何人都可以帮助我 - 出了什么问题?

2 个答案:

答案 0 :(得分:4)

感谢所有帮助我解决这个问题的人。重写了整个代码,现在它完美无缺:

__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中的不同线程中写入数据真是个坏主意,现在它返回语句(true \ false)和ip。

2)keep alive完全支持requests,但是如果要使用它,则必须创建对象Session的实例,并应用get仅限于它的方法:

s = requests.Session()
r = s.get('http://*****/?ip='+ip, timeout=None)

答案 1 :(得分:1)

此:

good_ip_list = []
bad_ip_list = []

与Python多处理混合是不安全的。正确的方法是从每个调用process_request返回一个元组(或其他东西),然后在最后将它们连接起来。从多个进程同时修改progress也是不安全的。我不是肯定你的错误是什么,但我敢打赌,这是一个同步问题,它杀死了整个Python。

删除共享状态,然后重试。