下面是我的代码,我对python来说真的很新。从我的下面的代码,我将实际创建多个线程(1000以上)。但在某些时候,近800个线程,我得到一条错误消息说"错误:无法启动新线程"。我确实读过一些关于threadpool的内容。我真的不明白。在我的代码中,我如何实现线程池?或者至少请以简单的方式向我解释
#!/usr/bin/python
import threading
import urllib
lock = threading.Lock()
def get_wip_info(query_str):
try:
temp = urllib.urlopen(query_str).read()
except:
temp = 'ERROR'
return temp
def makeURLcall(arg1, arg2, arg3, file_output, dowhat, result) :
url1 = "some URL call with args"
url2 = "some URL call with args"
if dowhat == "IN" :
result = get_wip_info(url1)
elif dowhat == "OUT" :
result = get_wip_info(url2)
lock.acquire()
report = open(file_output, "a")
report.writelines("%s - %s\n"%(serial, result))
report.close()
lock.release()
return
testername = "arg1"
stationcode = "arg2"
dowhat = "OUT"
result = "PASS"
file_source = "sourcefile.txt"
file_output = "resultfile.txt"
readfile = open(file_source, "r")
Data = readfile.readlines()
threads = []
for SNs in Data :
SNs = SNs.strip()
print SNs
thread = threading.Thread(target = makeURLcalls, args = (SNs, args1, testername, file_output, dowhat, result))
thread.start()
threads.append(thread)
for thread in threads :
thread.join()
答案 0 :(得分:4)
不要实现自己的线程池,使用Python附带的线程池。
在Python 3上,您可以使用concurrent.futures.ThreadPoolExecutor
显式使用线程,在Python 2.6及更高版本上,您可以import Pool
multiprocessing.dummy
与multiprocessing
API类似,但由线程而不是进程支持。
当然,如果你需要在CPython(参考解释器)中进行CPU绑定工作,你需要使用multiprocessing
,而不是multiprocessing.dummy
; Python线程适用于I / O绑定工作,但the GIL使它们对CPU绑定工作非常不利。
以下代码用Thread
的{{1}}替换您对multiprocessing.dummy
的明确使用,使用固定数量的工作人员,每个工作人员尽可能快地完成任务,而不是比拥有无限数量的一个工作线程。首先,由于本地I / O可能相当便宜,并且您想要同步输出,我们将使worker任务返回结果数据而不是自己写出来,并让主线程执行写操作到本地磁盘(不需要锁定,以及需要一遍又一遍地打开文件)。这会将Pool
更改为:
makeURLcall
现在代替替换显式线程的代码:
# Accept args as a single sequence to ease use of imap_unordered,
# and unpack on first line
def makeURLcall(args):
arg1, arg2, arg3, dowhat, result = args
url1 = "some URL call with args"
url2 = "some URL call with args"
if dowhat == "IN" :
result = get_wip_info(url1)
elif dowhat == "OUT" :
result = get_wip_info(url2)
return "%s - %s\n" % (serial, result)