进程的简介
进程的本质也是程序,而且是正在运行的程序
进程在运行过程中有三种状态,分别是就绪态、运行态以及阻塞态
进程可以分为四种,分别为同步阻塞、同步非阻塞、异步阻塞以及异步非阻塞。
同步是指一个任务的运行需要等待上一个任务的结束;异步是指将一个任务交给操作系统后继续去干其它的事,当该任务结束运行得到结果时只需告知一声即可。
阻塞是指等待其它任务结束或者在原地等待结果;非阻塞是指无序等待,当得到结果后通知一下即可。
在程序运行中,异步非阻塞效率最高。
一、进程的实现方法
1、直接调用Process模块
import time from multiprocessing import Process # 第一种:调用Process模块 def func(name): print("%s 启动了"%name) time.sleep(0.2) print("%s 结束了"%name) if __name__ == '__main__': p = Process(target=func,args=("egon",)) p.start() print("猪")
2、写一个类继承Process,调用内中的run方法
import time from multiprocessing import Process # 第二种:继承Process模块,调用内中的run方法 class MyProcess(Process): def __init__(self, name): super().__init__() self.name = name def run(self): print("%s 启动了" % self.name) time.sleep(0.2) print("%s 结束了" % self.name) if __name__ == '__main__': p = MyProcess("egon") p.start() print("猪")
二、join方法
子进程是由父进程开启的,父进程告诉操作系统创建一个子进程后就继续运行父进程的代码,父进程的代码可能会先运行完然后等待
子进程运行结束,为了保证每个子进程运行完后父进程再运行结束,可以在告知操作系统创建子进程之后调用join方法,保证创建每个子进程后
等待每个子进程的结束再运行并结束父进程。
同时开启了多个子进程的时候,可以每开启一个子进程的时候将其添加到一个列表中,添加完毕后再通过另一个for循环
将每个子进程取出,调用join方法。
join方法要等每个所有子进程都被告知给操作系统之后使用。
import time from multiprocessing import Process def func(i): print("%s 启动了"%i) time.sleep(i) print("%s 结束了"%i) lis = [] if __name__ == '__main__': for i in range(10): p = Process(target=func,args=(i,)) p.start() lis.append(p) for p in lis: p.join() print("猪")
三、每个进程中的数据
每一个进程间的数据是不能直接共用的,每个进程的数据都是独立的。
即使时子进程和父进程的数据也是相互独立的。
原因:每个进程再运行的时候,操作系统会给每个进程再内存中分配一块内存空间,也就导致了每个进程中的数据时相互独立的。
from multiprocessing import Process import time money = 100 def test(): global money money = 99999999 if __name__ == '__main__': p = Process(target=test) p.start() p.join() print(money)
四、进程相关的方法
current_process().pid:当前进程的PID
getpid():获取当前进程的PID
getppid():获取当前进程的父进程的PID
import time import os from multiprocessing import Process def fun(name): print("%s 开始运行!"%name, os.getpid(),os.getppid()) # 第一个是子进程的端口号,第二个是父进程的端口号,实际上是每个进程所在的python解释器的端口号 time.sleep(0.2) print("%s 结束运行!"%name, os.getpid(),os.getppid()) if __name__ == '__main__': p = Process(target=fun,args=("egon",)) p.start() print("猪",os.getpid(),os.getppid()) # 第一个是运行父进程的python解释器的端口号,第二个是运行解释器的pycharm编辑器的端口号
五、守护进程
守护进程顾名思义是为了保护某个进程的运行而被创建的。
当被保护的进程死亡时,守护进程也会随之死亡。
守护进程的设定应该在告诉操作系统创建该进程之前。
import time from multiprocessing import Process def func(name): print("%s 正在运行" % name) time.sleep(0.2) print("%s 陪葬" % name) if __name__ == '__main__': p = Process(target=func,args=("egon",)) p.daemon = True p.start() time.sleep(0.2) print("jason驾崩了!") time.sleep(1)
六、守护进程
当多个进程去访问同一个数据的时候,可以同时被多个进程拿到。
当每个进程对拿到的数据进行修改操作并保存到原来的位置的时候,一般情况下每个进程都会认为是自己对该数据做了操作。
但实际上每个进程的处理结果都会被下一个进程的处理结果覆盖,导致每个进程得到的反馈是都不正确。
此时需要一个机制,对每个进程处理数据的操作进行限制,在同一时间只有一个进程对该数据进行操作,等待上一个进程处理完后下一个进程才能对数据进行处理。
该机制就是互斥锁,给需要的数据在处理阶段进行上锁操作,每个进程需要拿到钥匙才能对数据进行操作,操作完毕后释放钥匙,下一个进程拿到钥匙后进行数据处理的操作。
PS:钥匙应该只提供一个
1 import time 2 from multiprocessing import Process,Lock 3 import json 4 5 6 def search(i): 7 with open("data.txt","r",encoding="utf-8") as f: 8 data = f.read() 9 dic = json.loads(data) 10 num = dic.get("ticket") 11 print("%s查询:还剩%s张票"%(i,num)) 12 13 def buy(i): 14 with open("data.txt","r",encoding="utf-8") as f: 15 data = f.read() 16 dic = json.loads(data) 17 num = dic.get("ticket") 18 time.sleep(0.2) # 模拟网络延迟 19 if num == 0: 20 print("没票了") 21 return 22 num -= 1 23 dic["ticket"] = num 24 with open("data.txt","w",encoding="utf-8") as a: 25 json.dump(dic,a) 26 print("%s抢票成功"%i) 27 28 def run(*args): 29 i,l = args 30 search(i) 31 l.acquire() 32 buy(i) 33 l.release() 34 35 if __name__ == '__main__': 36 l = Lock() 37 for i in range(10): 38 p = Process(target=run,args=(i,l),) 39 p.start() 40 print("zhu") 41 42 """ 43 0查询:还剩1张票 44 1查询:还剩1张票 45 2查询:还剩1张票 46 3查询:还剩1张票 47 4查询:还剩1张票 48 5查询:还剩1张票 49 7查询:还剩1张票 50 6查询:还剩1张票 51 8查询:还剩1张票 52 9查询:还剩1张票 53 0抢票成功 54 没票了 55 没票了 56 没票了 57 没票了 58 没票了 59 没票了 60 没票了 61 没票了 62 没票了 63 """
1 import time 2 from multiprocessing import Process,Lock 3 import json 4 5 6 def search(i): 7 with open("data.txt","r",encoding="utf-8") as f: 8 data = f.read() 9 dic = json.loads(data) 10 num = dic.get("ticket") 11 print("%s查询:还剩%s张票"%(i,num)) 12 13 def buy(i): 14 with open("data.txt","r",encoding="utf-8") as f: 15 data = f.read() 16 dic = json.loads(data) 17 num = dic.get("ticket") 18 time.sleep(0.2) # 模拟网络延迟 19 if num == 0: 20 print("没票了") 21 return 22 num -= 1 23 dic["ticket"] = num 24 with open("data.txt","w",encoding="utf-8") as a: 25 json.dump(dic,a) 26 print("%s抢票成功"%i) 27 28 def run(*args): 29 i,l = args 30 search(i) 31 # l.acquire() 32 buy(i) 33 # l.release() 34 35 if __name__ == '__main__': 36 l = Lock() 37 for i in range(10): 38 p = Process(target=run,args=(i,l),) 39 p.start() 40 print("zhu") 41 """ 42 0查询:还剩1张票 43 1查询:还剩1张票 44 3查询:还剩1张票 45 2查询:还剩1张票 46 4查询:还剩1张票 47 5查询:还剩1张票 48 6查询:还剩1张票 49 7查询:还剩1张票 50 8查询:还剩1张票 51 9查询:还剩1张票 52 0抢票成功 53 1抢票成功 54 3抢票成功 55 2抢票成功 56 4抢票成功 57 5抢票成功 58 6抢票成功 59 7抢票成功 60 8抢票成功 61 9抢票成功 62 """