1.并发编程
1 """""" 2 """计算机发展史""" 3 """ 4 1.计算机发展史 5 1.手工操作,穿孔卡片 6 同一个房间同一时刻只能运行一个程序,效率极低 7 2.联机批处理-随身听 8 磁带(小红,小王,小李) -->{ 输入机 -(程序,数据)-> 计算机 -(结果)-> 输出机}(用户) 9 效率虽然有所提升,但仍然很低 10 3.脱机批处理系统--提高CPU利用率 11 硬盘 - > 卫星机 - > 内存 - > 主机 12 作用:避免工作速率快的部件与慢的部件接触,拖慢运行速度 13 14 4.多道技术(*) 15 1.基于单核研究 16 单道 -> -> -> 17 ps:单道,运行a只能运行a,a完运行b 18 2.多道技术(a,b程序衔接紧密,当a进入IO时,调走cpu运行b,CPU空置很少) 19 多道: -> -> -> 20 -> -> -> 21 """ 22 """ 23 ***多道技术 24 1.空间上的复用, 25 多个程序共用一套计算机硬件 26 2.时间的复用 27 切换+保存状态 28 1.当一个程序遇到IO操作,操作系统会剥夺该程序CPU执行权限(提高cpu利用率,并且也不影响程序的执行效率) 29 2.当一个程序长时间占用cpu 操作系统也会剥夺该程序cpu执行权限(降低了程序的执行效率) 30 31 *并发:看起来像同时运行的就可以了 32 *并行:真正意义上的同时执行 33 单核和计算机不能实现并行,但是可以实现并发 34 """
2.2进程三态图.png
2.进程三个状态转换图.png
1 '''''' 2 """ 3 程序:一坨代码 4 进程:正在运行的程序 5 """ 6 """ 7 进程理论 8 """ 9 """ 10 1.时间片轮转法(多级反馈队列) 11 时间片:就好比将一秒等分成N份 12 linux可以给制定程序设置优先级 13 程序按优先级从高到低执行 14 15 """ 16 """ 17 2.进程三个状态转化 18 1.就绪态 19 程序在开始运行之后,并不是立即开始执行代码,而是进入就绪状态,等待操作系统调度开始运行 20 2.运行态 21 程序运行状态 22 # import time 23 # print('程序开始执行') 24 3.阻塞态 25 在这里遇到等待用户输入操作 26 程序进入阻塞状态 27 # name = input('name>>>').strip() 28 4.就绪态 29 用户输入之后,进程不是立即执行, 30 而是进入就绪状态,等待操作系统调度继续运行 31 5.运行态 32 # print(name) 33 6.阻塞态 34 # time.sleep(1) 35 7.就绪态 36 8.运行态 37 # print('程序运行结束') 38 9.结束 39 """
1 """""" 2 """ 3 1.同步异步: 4 表示任务的提交方式 5 6 同步: 7 任务提交后,原地等待的任务的执行并返回执行结果才走 , 8 期间不做任何事 9 (秩序层面的表现就是卡住了) 10 11 异步: 12 任务提交后,不在原地等待,而是继续执行下一行代码 13 (结果是要的 但是通过其他方式过去) 14 """ 15 # 异步 16 def func(): 17 print('kfgdldf') 18 p = func() 19 # 同步 20 def coun(): 21 x =1 22 return x 23 q = coun() 24 print(q) 25 """ 26 2.阻塞非阻塞 27 表示程序的运行状态 28 阻塞:阻塞态 29 非阻塞:运行态,就绪态 30 31 """ 32 """ 33 ps: 34 强调同步异步,阻塞非阻塞是两队概念,不能混为一谈 35 """
2.创建进程的两种方式
1 '''''' 2 """ 3 特性:进程间相互隔离的 4 """ 5 """ 6 1.创建进程方法一 直接实例化Process,将要执行用target传入 7 """ 8 9 10 11 from multiprocessing import Process 12 import time 13 import os 14 def task(name): 15 print("%s is running"%name) 16 print('son run!') 17 print('son:%s'%os.getpid()) 18 print('father:%s'%os.getppid()) 19 print('son over!') 20 time.sleep(3) 21 print('%s is over'%name) 22 23 24 if __name__ == '__main__': 25 # 创建一个进程对象 26 q = Process(target=task,args=('llx',)) 27 # 告诉操作系统帮你上见 28 print(os.getpid()) 29 q.start() 30 print('主') 31 """ 32 13144 33 主 34 llx is running 35 son run! 36 son:14280 37 father:13144 38 son over! 39 llx is over 40 """
1 """""" 2 from multiprocessing import Process 3 import time 4 import os 5 class MyProcess(Process): 6 def __init__(self,name): 7 super().__init__() 8 self.name = name 9 def run(self): 10 print("%s is running"%self.name) 11 print('son run:%s'%os.getpid()) 12 time.sleep(3) 13 print('father run:%s'%os.getppid()) 14 print("%s is over"%self.name) 15 if __name__ == '__main__': 16 p = MyProcess('llx') 17 p.start() 18 print('主') 19 """ 20 主 21 llx is running 22 son run:20772 23 father run:476 24 llx is over 25 """
1 """""" 2 """ 3 window 创建进程会将代码以模块的方式,从上往下执行一遍 4 5 linux会直接将代码完完整整的拷贝一份 6 """ 7 """ 8 window 创建进程一定要在if __name__ == '__main__': 9 代码块内创建,否则报错 10 """ 11 """ 12 本质: 13 创建进程 就是内存中重新开辟一块内存空间 14 将允许产生的代码丢进去, 15 一个进程对应在内存就是一块独立的内存空间 16 17 """ 18 """ 19 进程与进程之间数据是隔离的 20 无法直接交互 21 但是可以通过某些技术实现间接交互 22 """ 23 from multiprocessing import Process 24 import os 25 # def test(name): 26 # print("son:%s"%os.getpid()) 27 # print('f:%s'%os.getppid()) 28 # if __name__ == '__main__': 29 # p = Process(target=test,args=('llx',)) 30 # p.start() 31 # print('l') 32 class MyProcess(Process): 33 def __init__(self,name): 34 super().__init__() 35 self.name = name 36 def run(self): 37 print("son:%s"%os.getpid()) 38 print('f:%s'%os.getppid()) 39 if __name__ == '__main__': 40 p = MyProcess('llx') 41 p.start() 42 print('2')
3.jion方法
1 from multiprocessing import Process 2 import time 3 4 def test(name,i): 5 print('%s is running'%name) 6 time.sleep(i) 7 print('%s is over'%name) 8 if __name__ == '__main__': 9 p_list = [] 10 for i in range(3): 11 p = Process(target=test,args=('进程%s'%i,i)) 12 p.start() 13 p_list.append(p) 14 for p in p_list: 15 p.join() 16 """ 17 进程0 is running 18 进程0 is over 19 进程1 is running 20 进程2 is running 21 进程1 is over 22 进程2 is over 23 """
1 from multiprocessing import Process 2 import time 3 4 def test(name,i): 5 print('%s is running'%name) 6 time.sleep(i) 7 print('%s is over'%name) 8 if __name__ == '__main__': 9 p_list = [] 10 # for i in range(3): 11 # p = Process(target=test,args=('进程%s'%i,i)) 12 # p.start() 13 # p_list.append(p) 14 # for p in p_list: 15 # p.join() 16 p = Process(target=test,args=('a',1)) 17 p1 = Process(target=test,args=('b',2)) 18 p2 = Process(target=test,args=('c',3)) 19 start_time = time.time() 20 p.start() # 仅仅是告诉操作系统帮你创建一个进程 至于这个进程什么时候创 操作系统随机决定 21 p1.start() 22 p2.start() 23 p2.join() 24 p.join() 25 p1.join() 26 27 # 主进程代码等待子进程运行结束 才继续运行 28 # p.join() # 主进程代码等待子进程运行结束 29 print('主') 30 print(time.time() - start_time) 31 32 """ 33 a is running 34 b is running 35 c is running 36 a is over 37 b is over 38 c is over 39 主 40 3.23988938331604 41 """
4.进程之间数据是相互隔离的
1 from multiprocessing import Process 2 import time 3 4 5 money = 100 6 7 def test(): 8 global money 9 money = 99999999 10 print(money,'11111111111') 11 12 13 if __name__ == '__main__': 14 p = Process(target=test) 15 p.start() 16 p.join() 17 print(money) 18 19 ''' 20 99999999 11111111111 21 100 22 '''
5.进程对象及其他方法
1 """""" 2 """tasklist""" 3 ''' 4 5 映像名称 PID 会话名 会 6 话# 内存使用 7 ========================= ======== ================ ====== 8 ===== ============ 9 System Idle Process 0 Services 10 0 8 K 11 System 4 Services 12 0 24 K 13 Registry 120 Services 14 0 15,636 K 15 smss.exe 444 Services 16 0 524 K 17 csrss.exe 648 Services 18 0 1,832 K 19 wininit.exe 820 Services 20 0 2,592 K 21 services.exe 892 Services 22 0 6,428 K 23 lsass.exe 908 Services 24 0 10,344 K 25 svchost.exe 92 Services 26 0 356 K 27 ..................... 28 ''' 29 """tasklist|find 20052""" 30 ''' 31 E:\Python课堂内容整理\知识点框架\函数--装饰器--迭代器--生 32 成器--常用模块--ATM\day30并发编程>tasklist|findstr 20052 33 pycharm64.exe 20052 Console 34 5 862,692 K 35 36 '''
1 from multiprocessing import Process,current_process 2 import os 3 import time 4 5 def test(name): 6 print('%s is running'%name,current_process().pid) 7 print('%s is running'%name,'子进程%s'%os.getppid(),'父进程%s'%os.getppid()) 8 time.sleep(3) 9 print('%s is over'%name) 10 if __name__ == '__main__': 11 p = Process(target=test,args=('llx',)) 12 p.start() 13 p.terminate() # 1.杀死当前进程其实是告诉操作系统帮你杀死一个进程 14 #time.sleep(0.1) 15 print(p.is_alive()) # 2 .判断进程是否存活 16 print('主',os.getpid(),'主主进程%s'%os.getppid()) 17 18 """ 19 True 20 主 21484 主主进程20052 21 llx is running 21832 22 llx is running 子进程21484 父进程21484 23 llx is over 24 """ 25 """ 26 E:\Python课堂内容整理\知识点框架\函数--装饰器--迭代器--生 27 成器--常用模块--ATM\day30并发编程>tasklist|findstr 20052 28 pycharm64.exe 20052 Console 29 5 862,692 K 30 31 """
6.僵尸进城,和孤儿进程
1 '''''' 2 """僵尸进城""" 3 ''' 4 僵尸进城 5 6 值得是,子进程已经结束了,但是操作系统会保存一些进程信息,如PID,运行时间等,此时这个进程就称之为僵尸进程 7 8 僵尸进程如果太多将会占用大量的资源,造成系统无法开启新新进程 9 10 linux 中有一个wai/waitpid 用于父进程回收子进程资源 11 12 python会自动回收僵尸进程 13 ''' 14 """ 15 父进程回收子进程资源的两种方式 16 1.join方法 17 2.父进程正常死亡 18 所有的进程都会步入僵尸进程 19 """
1 '''''' 2 """ 3 孤儿进程 4 """ 5 """ 6 孤儿进程 7 8 指的是,父进程先结束 ,而子进程还在运行着, 9 10 孤儿进程无害,有 其存在的必要性 11 12 例如:qq开启了浏览器,qq先退出了 浏览器应该继续运行 13 14 孤儿进程会被操作系统接管 15 """ 16 ''' 17 孤儿进程 18 子进程没死 父进程意外死亡 19 20 针对linux会有儿童福利院(init) 如果父进程意外死亡他所创建的子进程都会被福利院收养 21 '''
7.守护进程
1 from multiprocessing import Process 2 import time 3 def test(name): 4 print('%s 总管正常活着'%name) 5 time.sleep(3) 6 print('%s总管正常死亡'%name) 7 if __name__ == '__main__': 8 p = Process(target=test,args=('llx',)) 9 # 设置守护进程,p.daemon = True 这一句话必须放在start语句之前 否则报错 10 p.daemon = True 11 p.start() 12 time.sleep(0.1) 13 print('皇帝jason寿正终寝') 14 ''' 15 为设置守护进程前: 16 皇帝jason寿正终寝 17 llx 总管正常活着 18 llx总管正常死亡 19 ''' 20 """设置为守护进程后""" 21 """ 22 llx 总管正常活着 23 皇帝jason寿正终寝 24 """
8.互斥锁
1 from multiprocessing import Process 2 # 导入锁的模块 3 from multiprocessing import Lock 4 import time 5 import json 6 7 # 查票 8 def search(i): 9 with open('data','r',encoding='utf-8') as f: 10 data = f.read() 11 t_d = json.loads(data) 12 print('用户%s查询余票为:%s'%(i,t_d.get('ticket'))) 13 14 # 买票 15 def buy(i): 16 with open('data','r',encoding='utf-8') as f: 17 data = f.read() 18 t_d = json.loads(data) 19 time.sleep(1) 20 if t_d.get('ticket') > 0: 21 # 票数减一 22 t_d['ticket'] -= 1 23 # 更新票数 24 with open('data','w',encoding='utf-8') as f: 25 json.dump(t_d,f) 26 print('用户%s抢票成功'%i) 27 else: 28 print('没票了') 29 30 31 def run(i,lock): 32 search(i) 33 lock.acquire() # 抢锁 只要有人抢到了锁 其他人必须等待该人释放锁 34 buy(i) 35 lock.release() # 释放锁 36 37 38 if __name__ == '__main__': 39 lock = Lock() 40 # 生成了一把锁 41 for i in range(10): 42 p = Process(target=run,args=(i,lock)) 43 p.start() 44 45 """ 46 用户0查询余票为:1 47 用户1查询余票为:1 48 用户2查询余票为:1 49 用户3查询余票为:1 50 用户4查询余票为:1 51 用户5查询余票为:1 52 用户6查询余票为:1 53 用户7查询余票为:1 54 用户8查询余票为:1 55 用户9查询余票为:1 56 用户0抢票成功 57 没票了 58 没票了 59 没票了 60 没票了 61 没票了 62 没票了 63 没票了 64 没票了 65 没票了 66 """
1 from multiprocessing import Process,Lock 2 import time 3 import json 4 5 # 查票 6 def search(i): 7 with open('date','r',encoding='utf-8')as f: 8 date = f.read() 9 t_d = json.loads(date) 10 print('用户%s查询余票为%s'%(i,t_d.get('ticket'))) 11 # p = search(1) 12 # print(p) 13 # """用户1查询余票为1""" 14 # 买票 15 def buy(i): 16 with open('date','r',encoding='utf-8')as f: 17 date = f.read() 18 t_d = json.loads(date) 19 time.sleep(1) 20 if t_d.get('ticket') > 0: 21 # 票数减一 22 t_d["ticket"] -= 1 23 # 更新票数 24 with open('date','w',encoding='utf-8')as f: 25 json.dump(t_d,f) 26 print('用户%s抢票成功'%i) 27 else: 28 print('没票了') 29 30 def run(i): 31 search(i) 32 buy(i) 33 if __name__ == '__main__': 34 for i in range(10): 35 p = Process(target=run,args=(i,)) 36 37 p.start()
1 {"ticket": 1}