1、进程理论
进程就是一个正在进行的过程或者一个任务,
1.1、进程与程序区别:
程序是一堆代码,进程是指的是程序的运行过程
1.2、多道技术:
空间上的复用、时间上的复用
多个任务复用、共享内存空间,进程之间的内存空间是相互隔离的
多个任务复用、共享cpu时间,cpu在多个任务之间来回切换
1、一个任务占用cpu的时间过长会被操作系统强行剥夺走cpu的执行权限,为了保证一个并发效果,降低效率。
2、一个任务遇到io操作会被操作系统剥夺走cpu的执行权限,为了实现 并发效果,这种情况下的并发可以提升效率。
2、开启进程的两种方式
方式一:
from multiprocessing import Process
import time
def task(name):
print('%s is running'% name)
time.sleep(3)
print('%s is down' % name)
if __name__ == '__main__':
obj = Process(target=task,args=('yzn',))
obj.start() # 操作系统发送一个开启子进程的信号
print('主')
输出结果:
主
yzn is running
yzn is down
方式二:
from multiprocessing import Process
import time
class Myprocsess(Process):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print('%s is running' % self.name)
time.sleep(3)
print('%s is down' % self.name)
if __name__ == '__main__':
p = Myprocsess('yzn')
p.start()
print('主')
3、进程对象join方法使用
让主进程原地等待,等待子进程运行完毕,不会影响子进程的执行
from multiprocessing import Process
import time
def task(name):
print('%s is running'% name)
time.sleep(3)
print('%s is down' % name)
if __name__ == '__main__':
obj = Process(target=task,args=('yzn',))
obj.start() # 想操作系统发送一个开启子进程的信号
obj.join() #添加join方法
print('主')
4、进程之间内存隔离
进程自检内存空间是相互隔离的
from multiprocessing import Process
n =100
def task():
global n
print(n,'1') #通过global复制全局的n 100,1
n =0
print(n,'2') #获取到n为0 0,2
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print(n) #获取全局中的值100
输出结果为:
100,1
0,2
100
5、进程对象其它相关方法
获取子进程的pid,主进程的pid
可以使用corrent_process 和getpid
1、corrent_process
from multiprocessing import Process,current_process
import time
def task():
print('%s is running' %current_process().pid)
time.sleep(30)
print('%s is done' %current_process().pid) # 查看子类pid
if __name__ == '__main__':
p =Process(target=task)
p.start()
print('主',current_process().pid) # 查看父类pid
2、getpid
from multiprocessing import Process
import time,os
def task():
print('% is running' %os.getpid()) #子进程pid
time.sleep(3)
print('%s is done'%os.getpid()) #子进程pid
if __name__ == '__main__':
p = Process(target=task)
p.start()
print('主',os.getpid()) # 主进程pid
6、僵尸进程与孤儿进程
僵尸进程解决办法:
1、主进程可以用过join()方法回收子进程(主动回收)
2、当主进程死了以后,操作系统自己可以发起回收(被动回收)
7、守护进程
守护进程本质就是一个子进程,该子进程的生命周期<=被守护进程的生命周期
from 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=('dsb',))
p.daemon=True #守护进程,在启动进程之前
p.start()
time.sleep(1)
print('皇上:egon正在die')
输入结果:
太监dsb
皇上:egon正在die
备注:这里设置等待时间time.sleep(1)时间没有超过子进程中的time.sleep(3)等待3秒下面的内容就不会显示,可以使用join()方法
8、互斥锁
互斥锁:共同操作一个文件造成错乱
加载 multiprocessing包中的Lock模块
import json
import time
import random
from multiprocessing import Process,Lock
def search(name):
with open('db.json','rt',encoding='utf-8') as f:
dic = json.load(f)
time.sleep(1)
print('%s查看余票为 %s' % (name, dic['count']))
def get(name):
with open('db.json', 'rt', encoding='utf-8') as f:
dic = json.load(f)
time.sleep(random.randint(1, 3))
if dic.get('count') > 0:
dic['count'] -= 1
with open('db.json', 'w', encoding='utf-8') as f:
json.dump(dic, f)
print('%s购票成功!!' % name)
else:
print('%s 查看到没有票了' % name)
def task(name,mutex):
search(name)
mutex.acquire() # 抢锁 对search进行加锁
get(name)
mutex.release() # 解锁 对数据进行修改的时候进行解锁
if __name__ == '__main__':
mutex = Lock() #使用Lock模块
for i in range(1, 10):
p = Process(target=task, args=('路人%s' % i,mutex))
p.start()
# p.join() # join只能将进程的任务整体编程串行