![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
并发编程 计算机发展史 进程理论 创建进程的两种方式(******) 进程方法join 进程对象及其他方法 进程间数据互相隔离 守护进程 互斥锁(*****) 多道技术: 1.空间上的复用 多个程序共用一套计算机硬件 2.时间上的复用 切换+保存状态 1.当一个程序遇到IO操作 操作系统会剥夺该程序的CPU执行权限(提高了CPU利用率,并且也不影响程序的执行效率) 2.当一个程序长时间占用CPU操作系统 并发:看起来同时运行就可以 并行:真正意义上的同时执行 单核的计算机能不能实现并发,但是可以并发 程序:一坨代码 进程:正在运行的程序 同步异步:表示的是任务提交方式, 同步:任务提交后,原地等待的任务执行 并拿到返回结果才走,期间不做任何事(程序层面的表现就是卡注了) 异步:任务提交后,不再原地等待,而是继续执行下一步代码(结果是要通过其他的方式获取) 阻塞非阻塞:表示的程序 运行的状态 阻塞:阻塞态 非阻塞:就绪态 运行态 强调:同步异步 阻塞非阻塞是两对概念不能混为一谈 僵尸进程 与 孤儿进程 父进程回收子进程资源的两种方式 1.join方法 2.父进程正常死亡 孤儿进程 子进程没死 父进程意外死亡 针对linux 会有儿童福利院(init) 如果父进程意外死亡 它所创建的子进程都会被福利院收养 守护进程: 设置守护进程,p.daemon = True 这一句话必须放在start语句之前 否则报错 互斥锁: 当多个进程操作同一份数据时,会造成数据的错乱 这个时候必须加锁处理 将并发变成串行 虽然降低了效率但是提高了数据的安全 ps: 1.锁不要轻易使用 : 容易造成死锁现象 2.只在处理数据的部分加锁,不要在全局加锁 锁必须在主进程中产生去子进程中使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process import time import os def test(name): print(f'{name} is running') print('son run') print(f'son:{os.getpid()}') # 求子进程 print(f'father:{os.getppid()}') print('son over') time.sleep(3) print(f'{name} is over') " windows 创建进程 会将代码以模块的模式从上往下执行一遍" \ "linux会直接将代码完完整整的拷贝一份" """ windows创建进程一定要在if __name__ == '__main__':代码块内创建 否则报错 """ if __name__ == '__main__': p = Process(target=test,args=('egon',)) # 创建一个进程对象 print(os.getpid()) # 求父进程 p.start() # 告诉操作系统帮你创作一个进程 print('主') """ 11584 主 egon is running son run son:10952 father:11584 son over egon is over """ """ 创建进程一的方法 : 直接实例化Process,将要执行target传入 """ """ 创建进程 就是在内存中重新开辟一块内存空间 将允许产生的代码丢进去 一个进程对应在内存就是一个独立的内存空间 进程与进程之间数据是隔离的 无法直接交互 但是可以通过某些技术实现间接交互 """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""""" """创建进程方法二:继承Process类,覆盖run方法,将任务放入run方法中""" from multiprocessing import Process import time import os class MyProcess(Process): def __init__(self,name): super().__init__() self.name = name def run(self): print(f'{self.name} is running') print(f'son run:{os.getpid()}') time.sleep(3) print(f'father run:{os.getppid()}') print(f'{self.name} is over') if __name__ == '__main__': p = MyProcess('llx') p.start() print('主') print(os.getpid()) """ 主 2460 llx is running son run:11516 father run:2460 llx is over """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process import time def test(name,i): print(f'{name} is running') time.sleep(i) print(f'{name} is over') if __name__ == '__main__': p_list = [] # for i in range(3): # p = Process(target=test,args=(f'进程{i}',i)) # p.start() # p_list.append(p) # for p in p_list: # p.join() # print(p_list) # """ # [<Process(Process-1, started)>, <Process(Process-2, started)>, <Process(Process-3, started)>] # # """ # """ # 进程0 is running # 进程0 is over # 进程1 is running # 进程2 is running # 进程1 is over # 进程2 is over # """ p = Process(target=test,args=('egon',1)) p1 = Process(target=test,args=('kevin',2)) p2 = Process(target=test,args=('jason',3)) start_time = time.time() p.start() # 仅仅是告诉操作系统帮助你创建一个进程 至于这个进程是什么时候创建 操作系统 随机决定 p1.start() p2.start() p2.join() p.join() p1.join() # 主进程代码等待子进程运行结束 才继续运行 # p.join() # 主进程代码等待子进程运行结束 print('主') print(time.time()-start_time) """ egon is running kevin is running egon is over jason is running kevin is over jason is over 主 15.402495861053467 """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process import time money = 100 def test(): global money money = 888888888888 if __name__ == '__main__': p = Process(target=test) p.start() p.join() print(money) # 100
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process,current_process import os import time def test(name): print(f'{current_process().pid} is running') print(f'{name} is running',f'子进程{os.getpid()}',f'父进程{os.getppid()}') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=test,args=('egon',)) p.start() p.terminate() # 杀死当前进程,其实是告诉操作系统帮你杀死一个进程 time.sleep(0.1) print(p.is_alive()) # 判断当前进程是否存在 print('主',current_process().pid) print('主',os.getpid(),f'主主进程{os.getppid()}') """ True 主 13240 主 13240 主主进程2236 15708 is running egon is running 子进程15708 父进程13240 egon is over # 杀死当前进程后 False 主 14320 主 14320 主主进程2236 """ """ 1.tasklist 2.D:\面试整理\重新开始\8.json socket 进程 线程 并发 锁(27-33)>tasklist| findstr 2236 pycharm64.exe 2236 Console 90 1,153,332 K """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process import time def test(name): print(f'{name}总管正常活着') time.sleep(3) print(f'{name}总管正常死亡') if __name__ == '__main__': p = Process(target=test,args=('egon',)) # p.daemon = True # # 将该进程设置为守护进程 这一句话必须放在start语句之前 否则报错 p.start() time.sleep(0.1) print('主进程 结束') """ 守护进程设置前: 主进程 结束 egon总管正常活着 egon总管正常死亡 守护进程设置后: 主进程 结束 """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process """导入锁的模块""" from multiprocessing import Lock import time import json """查票""" def search(i): with open('data','r',encoding='utf-8')as f: data = f.read() t_d = json.loads(data) print(f'用户{i}查询余票为:{t_d.get("ticket")}') """买票""" def buy(i): with open('data','r',encoding='utf-8')as f: data = f.read() t_d = json.loads(data) time.sleep(1) if t_d.get('ticket') > 0: """票数减一""" t_d['ticket'] -= 1 """更新票数""" with open('data','w',encoding='utf-8')as f: json.dump(t_d,f) print(f'用户{i}抢票成功') else: print('没票了') def run(i,mutex): search(i) mutex.acquire() # 抢锁 """ 只要有人抢到了锁 其他人必须等待该人释放锁 """ buy(i) mutex.release() # 释放锁 if __name__ == '__main__': mutex = Lock() # 生成一把锁 for i in range(10): p = Process(target=run,args=(i,mutex)) p.start() p.join()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""""" """ 队列:先进先出 堆栈:先进后出 """ from multiprocessing import Queue q = Queue(5) # 括号内可以传参数 表示的是这个队列的最大存储数 # 往队列中添加数据 q.put(1) q.put(2) q.put(3) print(q.full()) # 判断队列是否满了 q.put(4) q.put(5) # print(q.full()) # q.put(6) # 当队列满了之后 再放入数据 不会报错 会原地等待 直到队列中有数据被取走(阻塞态) print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.empty()) # # 判断队列中的数据是否取完 # print(q.get_nowait()) # # 取值 没有值不等待直接报错
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process,Queue def producer(q): q.put('hello llx') def consumer(q): print(q.get()) if __name__ == '__main__': q = Queue() p = Process(target=producer,args=(q,)) c = Process(target=consumer,args=(q,)) p.start() c.start() """ 子进程放数据 主进程获取数据 两个子进程相互放 取数据 """ """hello llx"""
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""""" """ 生产者:生产/制造数据的 消费者:消费/处理数据的 例子:做包子的,买包子的 1.做包子远比买包子的多 2.做包子的远比包子的少 供需不平衡的问题 """ from multiprocessing import Process,Queue,JoinableQueue import time import random def producer(name,food,q): for i in range(10): data = f'{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(f'{name}吃了{data}') time.sleep(random.random()) q.task_done() # 告诉队列你已经从队列中取出一个数据并且处理完毕了 if __name__ == '__main__': q = JoinableQueue() p = Process(target=producer,args=('主厨llx','面',q)) p1 = Process(target=producer,args=('配菜llw','凉菜',q)) c = Process(target=consumer,args=('刘利兴',q)) c1 = Process(target=consumer,args=('刘利伟',q)) p.start() p1.start() c.daemon = True c1.daemon = True c.start() c1.start() p.join() p1.join() q.join() # 等到队列中数据全部取出