一、首先要弄明白他的定义:
程序:就是我们电脑上的每个应用软件的一大堆代码,如果不去运行就是一个功能而已,一堆代码
进程:正在运行的程序
进程是一个实体,媒体哥进程都有他独立的内存空间
补充:1,同步和异步:针对任务的提交方式
同步:提交任务后原地等待任务的返回结果,期间不做任何事!(以前的存钱取钱)
异步:提交任务之后,不需要等待任务的返回结果,执行运行下一行代码
2.阻塞与非阻塞:针对对程序运行的状态
阻塞:遇到I操作---->行成阻塞态
非阻塞:就绪或者是运行态----->就绪态,运行态
二,
1.进程理论:就是正在云运行的程序
2.开启进程的两种方式(***)
1.函数定义下的进程创建
from multiprocessing import Process import def task(nmae): print(“% is singing”%name) time.sleep(2) print(“%s is ending”%name) if __name__ = "__main__": p1 = Process(targ =task, args = ("Ftimo",)) p1.start() #千万记住此时就是创建进程 print("主进程”) 上面是我直接手写的 —————————————————— from multiprocessing import Process import time def task(name): print("%s is singing"%name) time.sleep(3) print("%s in ending"%name) # 注意:在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍 # 一定要写在if __name__ == '__main__':代码块里面,自己补充:不然其他模块也可以不断循环给你创建进程 # 强调:函数一旦加括号,执行优先级最高--->立刻去执行代码(调用,传参子类) if __name__ == '__main__': p1 = Process(target=task, args=("Ftimo",)) p1.start() # 这是提示要创建进程:就是正在运行的程序 #time.sleep(5) #按正常是 print("主进程")
2.通过Process类的创建进程
from multiprocessing import Process import time #先定义类的继承进程方法与属性 class Myprocess(Process): def __init__(self, name): super().__init__() self.name = name def run(): #必须写run()方法 print("%s is dancing"% name) time.sleep(3) print("%s is ending"%name) if __name = "__main__": obj = Myprocess(''cris wu") obj.start() print("主进程”) ________________________ from multiprocessing import Process import time #第二。类继承方法 进程创建 class Myprocess(Process): def __init__(self, name): super().__init__() #先继承 self.name = name # 必须写run 方法 def run(self): print('%s is dancing'%self.name) time.sleep(2) print('%s is ending'%self.name) if __name__ == '__main__': obj = Myprocess("cris WU ") #实列化对象 obj.start() # time.sleep(3) print('主进程') # 主进程 # cris WU is dancing # cris WU is ending
3.进程对象的join方法(***)
其实就是将子进程先执行完毕 ------->再执行主进程
创建多个子进程:用到的for循环
from multiprocessing import Process import time def task(name, n): print('%s is dancing' %name) time.sleep(2) print('%s is ending' %name) if __name__ == '__main__': start_time = time.time() p_list = [] for i in range(4): #i=0,1,2,3 一会join 的时候是乱的 不影响 p = Process(target=task, args=('子进程%s' %i, i)) p.start() # 创建进程 p_list.append(p) for i in p_list: i.join() # join 作用是仅仅让主进程等待子进程结束后再运行 print('主进程', time.time()-start_time) # 整个程序运行到主进程的时间时间 -----》》》 0子进程 is singing 0子进程 is ending 1子进程 is singing 1子进程 is ending 2子进程 is singing 2子进程 is ending 3子进程 is singing 3子进程 is ending 主进程 13.191839456558228
4.进程之间内存隔离(***)
# 切记 进程与进程之间的数据是隔离!!! from multiprocessing import Process x=100 def task(): global x x= 10 if __name__ == '__main__': p = Process(target=task) p.start() p.join() # 让子进程运行完才到主进程 print("主进程",x) ————》》》主进程 100 数据间大家互不干预
5.进程对象其他相关方法
6.僵尸进程与孤儿进程
两种情况下会回收子进程的pid等信息
1.父进程正常结束
2.join方法
孤儿进程:父进程意外死亡
linux下:
init孤儿福利院;用来挥手孤儿进程所占用的资源
ps aux |grep 'Z'
7.守护进程
from multiprocessing import Process import time def task(name): print('%s 正活着'%name) time.sleep(3) print('%s正常死'%name) if __name__ == '__main__': p1 = Process(target=task, args=("egon厂公",)) p1.daemon = True #必须在p1.start()前 设置 注意 p1.start() # 创建进程 print('皇上PL正常死亡') -----》》》 皇上PL正常死亡
8.互斥锁(***) 锁千万不要随意去用
from multiprocessing import Process,Lock import time # 用户查询余票 import json def serach(i): with open('info','r',encoding='utf-8')as f: data = json.load(f) print('目前飞往北京的票数余额为:%s'%data.get('ticket')) #字典点get查询么有票不会报错 # 用户买票 def buy(i): # 用户买票之前害的查看当前是否还有票 with open('info','r',encoding='utf-8')as f: data = json.load(f) # 获取票数余额 print('当前飞往北京的票数余额为:%s'% data.get('ticket')) if data.get('ticket') >0: data['ticket'] -= 1 with open('info','w',encoding='utf-8')as f: json.dump(data,f) print('用户%s成功'%i ) else: print('用户%s余额票数为0'%i) # 设置单通道运行-->互斥锁 def run(i, mutex): serach(i) mutex.acquire() #抢锁 一把锁不能同时被多个人使用,没有抢到的就一直等待释放 buy(i) mutex.release() if __name__ == '__main__': mutex = Lock() for i in range(20): p = Process(target=run, args= (i,mutex)) p.start() ————》》》
目前飞往北京的票数余额为:4
当前飞往北京的票数余额为:4
用户3成功
目前飞往北京的票数余额为:3
当前飞往北京的票数余额为:3
用户1成功
目前飞往北京的票数余额为:2
当前飞往北京的票数余额为:2
用户0成功
目前飞往北京的票数余额为:1
当前飞往北京的票数余额为:1
用户2成功
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户4余额票数为0
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户5余额票数为0
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户6余额票数为0
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户7余额票数为0
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户8余额票数为0
目前飞往北京的票数余额为:0
当前飞往北京的票数余额为:0
用户9余额票数为0
牺牲了效率但是保证了数据的安全
锁一定要在主进程中创建,给子进程去用
解决多个进程操作同一份数据,造成数据不安全的情况
加锁会将并发变成串行
锁通常用在对数据操作的部分,并不是对进程全程加锁
mutex.acquire() # 抢锁 一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.release() # 释放锁
晚点上代码-------