线程和线程池的写法总结

690 阅读2分钟

ThreadPoolExecutor 的用法

导包

from concurrent.futures import ThreadPoolExecutor
  • 第一种使用submit + as_completed
with ThreadPoolExecutor(max_workers=2) as executor:
    fs = [executor.submit(func, args) for args in args_list]
    # as_completed 是生成器,即使慢,也要按照顺序进行输出
    for future in as_completed(fs):
        print(future.result())
  • 第二种就是使用map的方式
with ThreadPoolExecutor(max_workers=2) as executor:
    result = executor.map(map_fun, itr_arg)
    for res in result:
        print(res) #这个res就是你map_fun返回的结果,你可以在这里做进一步处理

Threading的使用

  • 默认情况
    • 主进程运行结束退出,非守护的子线程继续执行
    • 主进程运行结束退出,守护的子线程全部阵亡
import threading

def run():
    pass

if __name__ == '__main__':
    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        # 确保setDaemon()在start()之前
        # t.setDaemon(True) 是否设置守护,依据情况而定
        t.start()
  • join的使用(常用)
    • 主线程在设置join的部分进行等待,直到线程完成
import threading

def run():
    pass
    
if __name__ == '__main__':

    thread_list = []
    for i in range(5):
        t = threading.Thread(target=run)
        thread_list.append(t)

    for t in thread_list:
        t.setDaemon(True)
        t.start()

    for t in thread_list:
        t.join()
  • condition使用
class PersonA(threading.Thread):
    def __init__(self,cond):
        super().__init__(name="A")
        self.cond = cond
        
    def run(self):
        with self.cond: #为PersonA加上一把底层锁
            print('{}: Hello B,你在吗?'.format(self.name))
            self.cond.notify() #给B发出通知,释放掉B中wait加上的锁
            self.cond.wait() #释放掉A的底层锁,确保下一次收到notify()通知后线程能够切入。同时给A加上一把锁,阻塞之后程序的运行
            
 class PersonB(threading.Thread):
    def __init__(self,cond):
        super().__init__(name="B")
        self.cond = cond
        
    def run(self):
        with self.cond: #为PersonB加上一把底层锁
            self.cond.wait() # 使用wait方法阻塞后续程序,需要等待A发出通知,同时释放掉B的底层锁,保证线程可以切入进来
            print('{}: Hello A,我在'.format(self.name))
            self.cond.notify() # 给A发出一个通知,同时释放掉A中wait加上的锁
            
 if __name__ == '__main__':
    cond = threading.Condition()
    A = PersonA(cond)
    B = PersonB(cond)
    B.start() 
    A.start()
    #如果先调用A.start(),程序会阻塞,无法继续进行,原因在于先启动A时,notify()方法已经被发出,而此时B的wait()方法还没有启动,也就没法接受到notify()的通知,所以程序无法再继续
    
>> 
A: Hello B,你在吗?
B: Hello A,我在

threadpool的使用

import threadpool
poolsize = 10
pool = threadpool.ThreadPool(poolsize)

_requests = threadpool.makeRequests(func, data_list)
[pool.putRequest(req) for req in _requests]
pool.wait()