第三十四天
from threading import Thread import time n=100 def task(): global n n=0 if __name__ == '__main__': t=Thread(target=task) t.start() t.join() print('主',n) 结果: 主 0
进程间通行=>IPC
管道
队列=管道+锁
from multiprocessing import Queue 导入一个队列Queue q=Queue() 队列的大小 q.put(['first',]) put存放 q.put({'x':2}) q.put(3) q.put(4) print(q.get()) get取出 print(q.get()) print(q.get()) print(q.get()) 结果: ['first'] {'x': 2} 3 4
from multiprocessing import Queue q=Queue(3) q.put(['first',],block=True,timeout=3)(block队列满的时候锁的意思默认是True) q.put({'x':2},block=True,timeout=3)(timeout代表阻的时间三秒) q.put(3,block=True,timeout=3) q.put(4,block=True,timeout=3) block=True,timeout=-1 意思是如果阻住了一直等 q.put_nowait(1) #q.put(1,block=False)(不阻了,没有等候时间) q.put_nowait(2) q.put_nowait(3) q.put_nowait(4)到第四个会报错 print(q.get(block=True,timeout=3)) print(q.get(block=True,timeout=3)) print(q.get(block=True,timeout=3)) print(q.get(block=True,timeout=3)) 前面三个没有意义,到了第四个阻塞住了才有意义 print(q.get_nowait()) #q.get(block=false)(没有阻塞时间) print(q.get_nowait()) #q.get(block=false) print(q.get_nowait()) #q.get(block=false) print(q.get_nowait()) #q.get(block=false)(不等直接报错)
生产者消费者模型: 生产者和消费者中间加入一个介质,俩个不是互相沟通,而是互相像介质沟通
1. 什么是生产者消费者模型
生产者:代指生产数据的任务
消费者:代指处理数据的任务
该模型的工作方式: 生产生产数据传递消费者处理
实现方式: 生产者---->队列<------消费者
2. 为何要用
当程序中出现明细的两类任务,一类负责生产数据,一类负责处理数据 就可以引入生产者消费者模型来实现生产者与消费者的解耦合,平衡生产能力与消费能力,从提升效率
import time,random from multiprocessing import Process,Queue def producer(name,food,q): 生产者 for i in range(3): res='%s%s' %(food,i) time.sleep(random.randint(1,3)) #模拟生产数据的时间 q.put(res) print('厨师[%s]生产了<%s>' %(name,res)) def consumer(name,q): 消费者 while True: res=q.get() if res is None:break 生产者给消费者发结束信号 ,消费者收到就结束 time.sleep(random.randint(1,3)) #模拟处理数据的时间 print('吃货[%s]吃了<%s>' %(name,res)) if __name__ == '__main__': q=Queue() # 生产者们 p1=Process(target=producer,args=('小Egon','泔水',q)) p2=Process(target=producer,args=('中Egon','屎包子',q)) p3=Process(target=producer,args=('大Egon','腰子汤',q)) # 消费者们 c1=Process(target=consumer,args=('刘清正',q)) c2=Process(target=consumer,args=('吴三江',q)) p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() q.put(None) #q.put_nowait(None)(放在队列的最后面,一个消费者用一个,所以用俩) q.put(None) print('主')
了解:
import time,random from multiprocessing import Process,JoinableQueue def producer(name,food,q): for i in range(3): res='%s%s' %(food,i) time.sleep(random.randint(1,3)) #模拟生产数据的时间 q.put(res) print('厨师[%s]生产了<%s>' %(name,res)) def consumer(name,q): while True: res=q.get() time.sleep(random.randint(1,3)) #模拟处理数据的时间 print('吃货[%s]吃了<%s>' %(name,res)) q.task_done() 消费者发信号说取走了一个,接着可以做减法操作 if __name__ == '__main__': q=JoinableQueue() () # 生产者们 p1=Process(target=producer,args=('小Egon','泔水',q)) p2=Process(target=producer,args=('中Egon','屎包子',q)) p3=Process(target=producer,args=('大Egon','腰子汤',q)) # 消费者们 把消费者做成守护进程 c1=Process(target=consumer,args=('刘清正',q)) c2=Process(target=consumer,args=('吴三江',q)) c1.daemon=True c2.daemon=True p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() 主进程等p1结束在执行下一个代码 p2.join() p3.join() q.join() # 主进程等q结束,即q内数据被取干净了 print('主') 结果: 厨师[大Egon]生产了<腰子汤0> 厨师[小Egon]生产了<泔水0> 厨师[中Egon]生产了<屎包子0> 厨师[大Egon]生产了<腰子汤1> 吃货[吴三江]吃了<泔水0> 厨师[小Egon]生产了<泔水1> 厨师[中Egon]生产了<屎包子1> 吃货[刘清正]吃了<腰子汤0> 厨师[小Egon]生产了<泔水2> 厨师[中Egon]生产了<屎包子2> 厨师[大Egon]生产了<腰子汤2> 吃货[吴三江]吃了<屎包子0> 吃货[刘清正]吃了<腰子汤1> 吃货[吴三江]吃了<泔水1> 吃货[刘清正]吃了<屎包子1> 吃货[吴三江]吃了<泔水2> 吃货[刘清正]吃了<屎包子2> 吃货[吴三江]吃了<腰子汤2> 主
线程理论
1 什么是线程
进程其实一个资源单位,而进程内的线程才是cpu上的执行单位
线程其实指的就是代码的执行过程
2 为何要用线程
线程vs进程
1. 同一进程下的多个线程共享该进程内的资源
2. 创建线程的开销要远远小于进程
开启线程的俩种方式
第一种方式:
from threading import Thread import time def task(name): print('%s is running' %name) time.sleep(2) print('%s is done' %name) if __name__ == '__main__': t=Thread(target=task,args=('线程1',)) t.start() print('主') 结果: 线程1 is running 主 线程1 is done
第二种方式:
from threading import Thread import time class Mythread(Thread): def run(self): print('%s is running' %self.name) time.sleep(2) print('%s is done' %self.name) if __name__ == '__main__': t=Mythread() t.start() print('主') 结果: Thread-1 is running 主 Thread-1 is done
守护线程:
from threading import Thread import time def task(name): print('%s is running' %name) time.sleep(2) print('%s is done' %name) if __name__ == '__main__': t=Thread(target=task,args=('线程1',)) t.daemon=True t.start() print('主') 结果: 线程1 is running 主
from threading import Thread from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': # t1=Thread(target=foo) # t2=Thread(target=bar) t1=Process(target=foo) t2=Process(target=bar) t1.daemon=True t1.start() t2.start() print("main-------") 会出现的几种结果 # ''' # 123 # main------- # 456 # end456 # ''' # # ''' # main------- # 123 # 456 # end456 # ''' # # ''' # main------- # 456 # end456 # '''
线程互斥锁:
from threading import Thread,Lock import time mutex=Lock() n=100 def task(): global n mutex.acquire() temp=n time.sleep(0.1) n=temp-1 mutex.release() if __name__ == '__main__': t_l=[] for i in range(100): t=Thread(target=task) t_l.append(t) t.start() for t in t_l: t.join() print(n) 结果:0
线程特性介绍:
from threading import Thread,active_count,current_thread import time,os def task(): print('%s is running' %current_thread().name) time.sleep(2) if __name__ == '__main__': t=Thread(target=task,) t.start() t.join() print('主',active_count()) print('主',current_thread().name) 结果 : Thread-1 is running 主 1 主 MainThread
from threading import Thread import time,os def task(): print('%s is running' %os.getpid()) if __name__ == '__main__': t=Thread(target=task) t.start() print('主',os.getpid()) 结果: 8924 is running 主 8924
from threading import Thread import time n=100 def task(): global n n=0 if __name__ == '__main__': t=Thread(target=task) t.start() t.join() print('主',n) 结果: 主 0