'''
进程理论
程序:一堆代码
进程:正在运行的程序
进程是一个实体。每一个进程都有它自己独立的内存空间
同步和异步:针对任务的提交方式
同步:提交任务之后原地等待任务的返回结果,期间不做任何事
异步:提交任务后,不等待任务的返回结果,执行运行下一行代码
阻塞与非阻塞:针对程序运行的状态
阻塞:遇到io操作 》》阻塞态
非阻塞:就绪或者运行态 》》就绪态,运行态
1 进程理论
2 开启进程的两种方式 (***)
p.start(): 启动进程,并调用该进程中的p.run()
1
from multiprocessing import Process
import time
def task(name):
print('%s is running'%name)
time.sleep(3)
print('%s is over'%name)
注意,在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍
#一定要写在 if __name__ == '__main__': 代码块里面
强调:函数名一旦加括号,执行优先级最高,立刻执行
if __name__ == '__main__':
p1=Process(target=task,args=('egon',)) # 这一句话只是实例化了一个Process对象
p1.start() #告诉操作系统创建一个进程
print('主')
2
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 running' %self.name)
time.sleep(1)
print('%s is end'%self.name)
if __name__ == '__main__':
obj =MyProcess('egon')
obj.start()
print('主')
3 进程对象的join方法 (***)
join 的作用仅仅只是让主进程等待子进程的结束,不会影响子进程的运行
join(0.1) 让主进程等待子进程0.1秒 等待0.1秒后就不再等了
4 进程之间内存隔离 (***)
#记住 进程与进程之间数据是隔离的!!!
from multiprocessing import Process
x=100
def task():
global x
x=1
if __name__ == '__main__':
p =Process(target =task)
p.start() #在当前进程中启动子进程 异步 只是告诉操作系统启动子进程指令(系统命令,没有代码读取速度快)
p.join() #同步 等待子进程运行结束 才会继续执行下面的代码
print('主',x)
5 进程对象其它相关方法
p1.terminate() #杀死子进程 异步 发给系统命令不等待
time.sleep(0.1) #给系统一个反应时间
print(p1.is_alive()) #判断子进程是否存活
from multiprocessing import Process,current_process
current_process.pid() 子进程的进程id号
import os
os.getpid() 子进程端口号
os.getppid() 父进程的端口号 父进程还可以查看父进程 查看的是运行这个py文件的程序端口号
6 僵尸进程与孤儿进程
两种情况下会回收子进程的pid等信息
1 父进程正常结束
2 join方法
孤儿进程:父进程意外死亡
linux下
init孤儿福利院:用来回收孤儿进程所占用的资源
ps aux |grep 'Z'
7 守护进程
p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True
后,p不能创建自己的新进程,必须在p.start()之前设置
form multiprocessing import Process
import time
def task(name):
print('%s 正活着'%name)
time.sleep(3)
print('%s 正常死亡' %name)
if __name__ == '__main__':
p=Process(target=task,args=('egon总管',))
p.daemon =True #必须在p.start 开启进程命令之前声明
p.start()
print('皇帝jason正在死亡')
父进程死亡 子进程必须死
8 互斥锁 (***) 锁千万不要随意去用
牺牲了效率但是保证了数据的安全
锁一定要在主进程中创建,给子进程去用
解决多个进程操作同一份数据,造成数据不安全的情况
加锁会将并发变成串行
锁通常用在对数据操作的部分,并不是对进程全程加锁
mutex.acquire() #抢锁 一把锁不能同时被对个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.release() #释放锁
9 进程间通信》》》 IPC机制
10 生产者消费者模型 (***)
'''
创建进程的方式1:
from multiprocessing import Process
import time
def task(name):
print('%s is running'%name)
time.sleep(3)
print('%s is over'%name)
if __name__ == '__main__':
p1=Process(target=task,args=('egon',)) #这一句话只是实例化了一个Process对象
p1.start() #告诉操作系统创建一个进程
print('主')
主
egon is running
egon is over
创建进程2
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 running'%self.name)
time.sleep(1)
print('%s is end'%self.name)
if __name__ == '__main__':
obj=MyProcess('egon')
obj.start()
print('主')
主
egon is running
egon is end
join 方法
from multiprocessing import Process
import time
def task(name,n):
print('%s is running'%name)
time.sleep(n)
print('%s is over'%name)
if __name__ == '__main__':
start_time=time.time()
p_list=[]
for i in range(1,4):
p=Process(target=task,args=('子进程%s'%i,i))
p.start()
p_list.append(p)
for i in p_list:
i.join() #主进程等待子进程结束,才能继续运行 最后一个需要等待3秒可以把前两个子进程都运行完(并行)
# p1=Process(target=task,args=('egon',1))
# start_time=time.time()
# p1.start() #千万要知道,这句话只是告诉操作系统需要进程 由系统分配创建进程
# p1.join() #主进程等待子进程结束 才继续运行
#
# egon is running
# egon is over
# 主
# 1.1000628471374512
print('主',time.time()-start_time)
#join的作用仅仅只是让主进程等待子进程的结束,不会影响子进程的运行
#随机的一次
子进程2 is running
子进程3 is running
子进程1 is running
子进程1 is over
子进程2 is over
子进程3 is over
主
3.1401796340942383
# 4 进程间数据隔离
from multiprocessing import Process
x =100 #主进程
def task():
global x
x =1 #子进程
if __name__ == '__main__':
p=Process(target=task)
p.start()
p.join()
print('主',x)
主 100
进程与进程之间数据是隔离的
# 5 进程对象其他相关方法
from multiprocessing import Process,current_process
import time
def task():
print('%s is running'%current_process().pid)
time.sleep(3)
print('%s is over'%current_process().pid)
# if __name__ == '__main__':
# p1=Process(target=task)
# p1.start()
# print('主')
# 主
# 5660 is running
# 5660 is over
# if __name__ == '__main__':
# p1=Process(target=task)
# p1.start()
# p1.terminate() #杀死子进程的指令 代码读取速度比系统块 如果没有睡眠等待时间
# print(p1.is_alive()) #判断子进程是否存活
# print('主')
#
# True
# 主
if __name__ == '__main__':
p1=Process(target=task)
p1.start()
p1.terminate() #杀死子进程的指令 代码读取速度比系统块 如果没有睡眠等待时间
time.sleep(0.1)
print(p1.is_alive()) #判断子进程是否存活
print('主')
False
主
# 守护进程
from multiprocessing import Process
import time
def task(name):
print('%s 正活着'%name)
time.sleep(1)
print('%s 正常死亡'%name)
if __name__ == '__main__':
p=Process(target=task,args=('egon总管',))
p.daemon=True #必须在p.start开启进程命令之前声明
p.start() #异步 不等待子进程
# p.daemon = True #写在后面会报错
print('皇帝jaso正在死亡')
皇帝jaso正在死亡 #父进程结束,子进程也结束
互斥锁
from multiprocessing import Process,Lock
import json
import time
import random
def search(i):
with open('info','r',encoding='utf-8')as f:
data =json.load(f)
print('用户%s查询余票数:%s'%(i,data.get('ticket')))
def buy(i):
#买票之前害的先查有没有票
with open('info','r',encoding='utf-8')as f:
data=json.load(f)
time.sleep(random.randint(1,3)) #模拟网络延迟
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):
search(i)
mutex.acquire() #抢锁 一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.acquire() #释放锁
if __name__ == '__main__':
mutex=Lock()
for i in range(1,11):
p=Process(target=run,args=(i,mutex))
p.start()
用户1查询余票数:1
用户3查询余票数:1
用户9查询余票数:1
用户4查询余票数:1
用户7查询余票数:1
用户8查询余票数:1
用户5查询余票数:1
用户2查询余票数:1
用户6查询余票数:1
用户10查询余票数:1
用户1抢票成功