进程间通信
队列和堆栈
队列:先进先出 排队
堆栈:先进后出 往衣柜里面放衣服
from multiprocessing import Queue q = Queue(5) # 括号内可以传参数 表示的是这个队列最大的存储数 # 向队列中添加数据 q.put(1) q.put(2) q.put(3) q.put(4) q.put(5) # q.put(6) # 当队列满了之后 再次放入数据 不会报错 会在原地等待 直到队列中有数据被取走(阻塞态) # 取值 # full 判断队列是否满了 返回布尔值 # empty 判断队列中数据是否为空 返回布尔值 # get._nowait 取值 没有值的话不等地啊 直接报错 print(q.get()) print(q.get()) print(q.full()) # False 判断队列是否满了 返回布尔值 print(q.get()) print(q.empty()) # False 判断队列中数据是否为空 返回布尔值 print(q.get()) print(q.get()) print(q.full()) # True 判断队列是否满了 print(q.get()) #当队列中的数据被取完之后 再次获取 程序会阻塞 直到有人往队列中放值 # print(q.get_nowait()) # 取值 没有值不等待直接报错
进程间通信IPC机制
from multiprocessing import Process,Queue def producer(q): q.put('hello') def consumer(q): print(q.get()) if __name__ == '__main__': q = Queue() p = Process(target=producer,args=(q,)) p.start() c = Process(target=consumer,args=(q,)) c.start() ''' 子进程放数据 主进程获取数据 两个子进程相互放 取数据 '''
生产者消费者模型
''' 什么是生产者 生产者: 生产/制造数据的 什么是消费者 消费者: 消费/处理数据的 例子:生产者 做包子的 消费者 买包子的 1 做包子的远比买包子的多 2 做包子的远比买包子的少 供需不平衡的问题 ''' from multiprocessing import Process,Queue,JoinableQueue import random import time def producer(name,food,q): for i in range(10): data = '%s生产了%s%s'%(name,food,i) time.sleep(random.random()) q.put(data) print(data) def consumer(name,q): while True: data = q.get() if data == None: break print('%s吃了%s'%(name,data)) time.sleep(random.random()) q.task_done() # 告诉队列你已经从队列中取出一个数据 并且处理完毕了 if __name__ == '__main__': # q = Queue q = JoinableQueue() p = Process(target=producer,args=('大厨egon','馒头',q)) p1 = Process(target=producer,args=('跟班tank','生蚝',q)) c = Process(target=consumer,args=('jason',q)) c1 = Process(target=consumer,args=('吃货jerry',q)) p.start() p1.start() c.daemon = True c1.daemon = True c.start() c1.start() p.join() p1.join() q.join() # 等待队列中数据全部取出 # q.put(None) # q.put(None)
线程
什么是线程
进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物
进程:资源单位
线程:执行单位
范例:
将内存比喻成工厂
那么进程就相当于工厂里面的车间
而你的线程就相当于车间里面的流水线
ps: 每个进程都自带一个线程
为什么要有线程
开进程
1 申请内存空间 消耗资源
2 类似于'拷贝代码' 消耗资源
开线程
1 一个进程内可以起多个线程,并且线程与线程之间数据是共享的
ps: 开启线程的开销要远远小于开启进程的开销
如何用线程
创建线程的方式

from threading import Thread import time def task(name): print('%s is running'%name) time.sleep(3) print('%s is over'%name) # 开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内 t = Thread(target=task,args=('egon',)) t.start() #告诉操作系统 开辟一个线程 只不过线程的开销远远小于进程 # 小到代码执行完毕 线程就已经开启了 print('主')

from threading import Thread import time class MyThread(Thread): def __init__(self,name): super().__init__() self.name = name def run(self): print('%s is running'%self.name) time.sleep(3) print('%s is over'%self.name) t = MyThread('egon',) t.start() print('主')
线程对象其他方法
from threading import Thread,current_thread,active_count import time import os def task(name,i): print('%s is running'%name) # print('current_Thread:',current_thread().name) # print('子',os.getpid()) time.sleep(i) print('%s is over'%name) # 开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内 t = Thread(target=task,args=('egon',2)) t1 = Thread(target=task,args=('jason',1)) t.start() #告诉操作系统 开辟一个线程 只不过线程的开销远远小于进程 # 小到代码执行完毕 线程就已经开启了 t1.start() print('当前正在活跃的线程数',active_count()) print('主') # print('主current_Thread:',current_thread().name) # print('主',os.getpid())
守护线程
from threading import Thread,current_thread import time def task(i): print(current_thread().name) time.sleep(i) print('GG') # for i in range(3): # t = Thread(target=task,args=(i,)) # t.start() t = Thread(target=task,args=(1,)) t.daemon = True t.start() print('主') # 主线程运行结束之后需要等待子线程结束才能结束呢? ''' 主线程的结束意味着进程的结束 主线程必须等待其他非守护线程的结束才能结束 (意味着子线程在运行程序的时候需要使用进程中的资源, 而主线程一旦结束了资源也就销毁了) '''
线程间通信
from threading import Thread money = 666 def task(): global money money = 999 t = Thread(target=task) t.start() t.join() print(money)
互斥锁
from threading import Thread,Lock import time n = 100 def task(mutex): global n mutex.acquire() tem = n time.sleep(0.1) n = tem - 1 mutex.release() t_list = [] mutex = Lock() for i in range(100): t = Thread(target=task,args=(mutex,)) t.start() t_list.append(t) for t in t_list: t.join() print(n)
小练习
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.daemon = True t1.start() t2.start() print("main-------") 输出结果 123 456 main------- # 3秒后输出 end123 end456