zoukankan      html  css  js  c++  java
  • 记一次 python多线程+Queue的坑逼之旅

    背景~

    在爬虫中,需要用到代理ip,本人写了一个模块来获取和过滤代理ip(用多线程过滤,),,,在主线程中判断可用的代理ip少于一定值了,获取新的可用ip,问题来了。。多次调用代理ip模块之后报错:

    can't start new thread                         !!!!!!!!!!!!!!!?????????????????????????

    what the fuck!!!!神马鬼,一次只开20个线程怎么会创建不了新的线程,,在检查之后发现打开的线程功能完成之后虽然结束了,但是还占用着资源,,(没释放,在死循环??),持续打开新的线程使我的电脑到达所能开启的最大线程了!!!!!!

    于是写了一个例子来测试一下结果,代码如下:

    import threading , time
    from queue import Queue
    
    class BdSpider(threading.Thread):
        def __init__(self, waiting):
            super(BdSpider, self).__init__()
            self.waiting = waitingdef run(self):
         flag = True 
    while flag: ipone = self.waiting.get() self.waiting.task_done()
           if self.waiting.empty():
             print("ppppppppppppppppppppppppppppp")
            flag = False
    def ipAction(): for i in range(10): aaa = [] wait_list = Queue() thread_num = 20 for keyip in range(2000): if keyip: wait_list.put(keyip)#往Queue添加 for ii in range(100): print(ii + i*100) thread = BdSpider(wait_list) thread.setDaemon(True)#设置守护进程 thread.start() aaa.append(thread) wait_list.join() print("-------------------------------") print(threading.active_count())#打印当前线程数 ipAction() print("main ------") print(threading.active_count())

    打印当前的线程数量确实是在持续增加,,一直到极限,,,,

    刚开始一直在找怎么把线程强制杀死,,,怎么释放线程占得资源,,,,,在网上找了两天(日乐购),,测试各种各样的可能,,no!!!!!!!!!!!!

    代码中重写类中run方法判断队列为空只走了一次!!!!!!!!!!!!!!!!

    ??????????why

    心中无数个草拟吗奔腾而过~~

    于是乎查找与Queue有关的东西,功夫不负有心人,终于在python的官网找到了答案,官网原话和例子:

    Queue.join

    阻止直到队列中的所有项目都被获取并处理。

    每当项目添加到队列时,未完成任务的计数就会增加。每当消费者线程调用task_done()以指示该项目已被检索并且其上的所有工作都已完成时,计数就会下降当未完成任务的数量降至零时,join()取消阻止。如何等待排队任务完成的示例:

    def worker():
        while True:
            item = q.get()
            if item is None:
                break
            do_work(item)
            q.task_done()
    
    q = queue.Queue()
    threads = []
    for i in range(num_worker_threads):
        t = threading.Thread(target=worker)
        t.start()
        threads.append(t)
    
    for item in source():
        q.put(item)
    
    # block until all tasks are done
    q.join()
    
    # stop workers
    for i in range(num_worker_threads):
        q.put(None)
    for t in threads:
        t.join()

    ,,,,照着更改之后,解决问题,,打印线程数量为1(主线程),,,,

    有一个疑问?:为什么开启的100个线程只有1个判断为空,子线程结束,剩余的99个线程为什么不判断,不跳出!!!!!!(有大佬懂得请不吝赐教)

    总结:

    以我的理解,100个线程中只有一个线程判断为空,出来了,join结束,不知道剩余的99个线程没判断为空,,不知道死在里边哪里了。官网例子是在队列重新put进100个None,给100个线程判断跳出,,然后就都出来了(线程全部结束)

    print(threading.active_count()) 打印一下线程数量,,只剩下主线程,
     
    over~


  • 相关阅读:
    出栈序列的可能性判定
    阿里离线数据处理平台2013暑期学校
    终于算完了这道『1+1』
    数据结构学习笔记之一 链表
    经典解释监视器和对象锁
    Sybase中字符串替换函数 STR REPLACE
    使用Arrays sort 方法進行排序
    clustered和nonclustered索引的区别
    Java序列化的作用和反序列化
    Java多线程下载并具断点续传功能JAR
  • 原文地址:https://www.cnblogs.com/dahuag/p/9766015.html
Copyright © 2011-2022 走看看