python多线程和进程
1.queue线程通讯
生产者和消费者 main方法2.task_done和join
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。
可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。
3.线程Condition
Condition(条件变量)通常与一个锁关联。需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。
可以认为,除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中的等待阻塞状态,直到另一个线程调用notify()/notifyAll()通知;得到通知后线程进入锁定池等待锁定。
Condition():
acquire(): 线程锁
release(): 释放锁
wait(timeout): 线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。
notify(n=1): 通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notify()不会主动释放Lock。
notifyAll(): 如果wait状态线程比较多,notifyAll的作用就是通知所有线程
运行结果实例应用:生产者与消费者
实现场景:当a同学王火锅里面添加鱼丸加满后(最多5个,加满后通知b去吃掉),通知b同学去吃掉鱼丸(吃到0的时候通知a同学继续添加)
生产者 消费者4.线程Semaphore
#Semaphore 是用于控制进入数量的锁
#文件(读、写)写一般只是用于一个线程写,读可以允许有多个
#做爬虫
控制代码进入线程的数量,控制并发数量,可以使用信号量Semaphore。
1、定义信号量sem = threading.Semaphore(3) #3为并发数量
2、消耗信号量 sem.acquire()
3、释放信号量 sem.release()
爬虫代码生产者获取锁,消费者完成后释放锁。
main方法5.线程futures
单个提交 批量提交wait(all_task, return_when=FIRST_COMPLETED) 表示单第一个执行成功后就继续下去
return_when没有的时候表示全部执行完成
6.多进程和多进程选择
#多进程编程
#耗cpu的操作,用多进程编程, 对于io操作来说,
# 使用多线程编程,进程切换代价要高于线程
#1. 对于耗费cpu的操作,多进程由于多线程
消费cpu多进程优于多线程#2. 对于io操作来说,多线程优于多进程
IO操作7.多进程编程和多进程之间的通讯
多线程可以共享变量,多进程是不能共享变量的
父进程运行结束后立即结束运行,但是子进程还是继续运行
多进程的Queue 多线程的Queue#共享全局变量不能适用于多进程编程,可以适用于多线程
#multiprocessing中的queue不能用于pool进程池
#pool中的进程间通信需要使用manager中的queue
python中3个Queue 多进程编程 只使用2个进程之间通讯