• PYTHON__Thread达到上限的解决方案(设置线程上限)


    Can't start new thread解决方案(设置线程上限)

    背景:

    在编写一个爬虫的时候,检查用多线程来检测结果有效性的时候,线程启动过多报错:

    thread.error: can't start new thread

    方案:使用Thread中的event,并进行上锁设置来解决。

    原因:这个是由于每台计算机能进行的并行是有上限的,经过测试本机的上限为1023个左右(win7 64位,i3 2核4线程),可以进行设置提高上限,但我觉得此处没有必要,也不方便扩展,所以想自行定义一个并行的上限数进行处理。

    参考:在多次百度无果之后,选择了google,查看了国外的一些评论和解决方案,在google学术中搜索“python thread number limit”,下载了此篇pdf,13-14页中找到了解决方案,果然是老外做的东西,老外更懂啊。

    http://python-ray.googlecode.com/hg-history/425d613ba8a2c7bd367b573018df45e5ec474428/doc/PyThreads.pdf

    解决方案:

    具体解决方案如下,对应的代码加上了注释。

     1 #coding=utf-8
     2 import threading
     3 
     4 class scanner(threading.Thread):
     5     tlist=[] #用来存储队列的线程
     6     maxthreads=100 # int(sys.argv[2])最大的并发数量,此处我设置为100,测试下系统最大支持1000多个
     7     evnt=threading.Event()#用事件来让超过最大线程设置的并发程序等待
     8     lck=threading.Lock() #线程锁
     9     def __init__(self):
    10         threading.Thread.__init__(self)
    11     def run(self):
    12         try:
    13             pass
    14         except Exception,e:
    15             print e.message
    16         #以下用来将完成的线程移除线程队列
    17         scanner.lck.acquire()
    18         scanner.tlist.remove(self)
    19         #如果移除此完成的队列线程数刚好达到99,则说明有线程在等待执行,那么我们释放event,让等待事件执行
    20         if len(scanner.tlist)==scanner.maxthreads-1:
    21             scanner.evnt.set()
    22             scanner.evnt.clear()
    23         scanner.lck.release()
    24     def newthread(proxy,counter):
    25         scanner.lck.acquire()#上锁
    26         sc=scanner()
    27         scanner.tlist.append(sc)
    28         scanner.lck.release()#解锁
    29         sc.start()
    30     #将新线程方法定义为静态变量,供调用
    31     newthread=staticmethod(newthread)
    32 
    33 def runscan():
    34     for i in 1 .. 100:
    35         scanner.lck.acquire()
    36         #如果目前线程队列超过了设定的上线则等待。
    37         if len(scanner.tlist)>=scanner.maxthreads:
    38             scanner.lck.release()
    39             scanner.evnt.wait()#scanner.evnt.set()遇到set事件则等待结束
    40         else:
    41             scanner.lck.release()
    42         scanner.newthread(proxy,counter)
    43         
    44     for t in scanner.tlist:
    45         t.join()#join的操作使得后面的程序等待线程的执行完成才继续
    46 
    47 if __name__=="__main__":
    48     runscan()
  • 相关阅读:
    java进度条
    获取程序运行环境
    struts2学习笔记(二) 初识Struts2
    HttpComponents入门解析
    C#编码规范
    js实现GBK编码
    struts2学习笔记(一) MVC模式
    mysql数据库操作类
    java类装载器原理
    [Study Note] NHibernate in Action 20100729
  • 原文地址:https://www.cnblogs.com/freeideas/p/3060812.html
Copyright © 2020-2023  润新知