创建进程的两种方式、join方法、进程间的数据隔离问题、进程对象以及其他方法、守护进程、互斥锁等

创建进程的两种方式

创建进程的过程:

创建进程就是在内存中重新开辟一块内存空间
将允许产生的代码丢进去
一个进程对应在内存就是一块独立的内存空间
进程与进程之间数据是隔离的 无法直接交互
但是可以通过某些技术实现间接交互
使用process模块时需要注意:
在Windows操作系统中由于没有fork(linux操作系统中创建进程的机制),
在创建子进程的时候会自动 import 启动它的这个文件,而在 import 的时候又执行了整个文件。
因此如果将process()直接写在文件中就会无限递归创建子进程报错。
所以必须把创建子进程的部分使用if __name__ ==‘__main__’ 判断保护起来,import 的时候 ,就不会递归运行了。

第一种方式:

 1 from multiprocessing import Process
 2 import time
 3 
 4 
 5 def test(name):
 6     print('%s is running'%name)
 7     time.sleep(3)
 8     print('%s is over'%name)
 9 
10 """
11 windows创建进程会将代码以模块的方式 从上往下执行一遍
12 linux会直接将代码完完整整的拷贝一份
13 
14 
15 windows创建进程一定要在if __name__ == '__main__':代码块内创建  否则报错
16 """
17 if __name__ == '__main__':
18     p = Process(target=test,args=('egon',))  # 创建一个进程对象
19     p.start()  # 告诉操作系统帮你创建一个进程
20     print('')
创建进程的方式一

第二种方式:

 1 # 创建进程的第二种方式
 2 from multiprocessing import Process
 3 import time
 4 
 5 
 6 class MyProcess(Process):
 7     def __init__(self,name):
 8         super().__init__()
 9         self.name = name
10 
11     def run(self):
12         print('%s is running' % self.name)
13         time.sleep(3)
14         print('%s is over' % self.name)
15 
16 
17 if __name__ == '__main__':
18     p = MyProcess('egon')
19     p.start()
20     print('')
创建进程的方式二

join方法:

p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
注意:
多个进程同时运行(注意,子进程的执行顺序不是根据启动顺序决定的)
 1 import time
 2 from multiprocessing import Process
 3 
 4 def f(name):
 5     print('hello', name)
 6     time.sleep(1)
 7     print('我是子进程')
 8 
 9 
10 if __name__ == '__main__':
11     p = Process(target=f, args=('bob',))
12     p.start()
13     #p.join()
14     print('我是父进程')
join方法
 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=('egon',1))
17     p1 = Process(target=test,args=('kevin',2))
18     p2 = Process(target=test,args=('jason',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)
join方法详细版本

进程间的数据的隔离问题:

对进程中数据修改不会影响其他进程中的数据!

 1 from multiprocessing import Process
 2 
 3 def work():
 4     global n
 5     n=0
 6     print('子进程内: ',n)
 7 
 8 
 9 if __name__ == '__main__':
10     n = 100
11     p=Process(target=work)
12     p.start()
13     print('主进程内: ',n)
进程间的数据隔离问题

进程中的其他常用方法:

p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
p.is_alive():如果p仍然运行,返回True
 1 from multiprocessing import Process,current_process
 2 import os
 3 import time
 4 
 5 
 6 def test(name):
 7     # print('%s is running'%name,current_process().pid)
 8     print('%s is running'%name,'子进程%s'%os.getpid(),'父进程%s'%os.getppid())
 9     time.sleep(3)
10     print('%s is over'%name)
11 
12 
13 if __name__ == '__main__':
14     p = Process(target=test,args=('egon',))
15     p.start()
16     p.terminate()  # 杀死当前进程  其实是告诉操作系统帮你杀死一个进程
17     time.sleep(0.1)
18     print(p.is_alive())  # 判断进程是否存活
19     # print('主',current_process().pid)
20     print('', os.getpid(), '主主进程:%s'%os.getppid())
用法
属性:
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
2 p.name:进程的名称
3 p.pid:进程的pid
 1 from multiprocessing import Process
 2 import time
 3 
 4 
 5 def test(name):
 6     print('%s总管正常活着'%name)
 7     time.sleep(3)
 8     print('%s总管正常死亡'%name)
 9 
10 
11 if __name__ == '__main__':
12     p = Process(target=test,args=('egon',))
13     p.daemon = True  # 将该进程设置为守护进程   这一句话必须放在start语句之前 否则报错
14     p.start()
15     time.sleep(0.1)
16     print('皇帝jason寿正终寝')
守护进程

互斥锁:

 1 from multiprocessing import Process,Lock
 2 import time
 3 import json
 4 
 5 # 查票
 6 def search(i):
 7     with open('data','r',encoding='utf-8') as f:
 8         data = f.read()
 9     t_d = json.loads(data)
10     print('用户%s查询余票为:%s'%(i,t_d.get('ticket')))
11 
12 # 买票
13 def buy(i):
14     with open('data','r',encoding='utf-8') as f:
15         data = f.read()
16     t_d = json.loads(data)
17     time.sleep(1)
18     if t_d.get('ticket') > 0:
19         # 票数减一
20         t_d['ticket'] -= 1
21         # 更新票数
22         with open('data','w',encoding='utf-8') as f:
23             json.dump(t_d,f)
24         print('用户%s抢票成功'%i)
25     else:
26         print('没票了')
27 
28 
29 def run(i,mutex):
30     search(i)
31     mutex.acquire()  # 抢锁  只要有人抢到了锁 其他人必须等待该人释放锁
32     buy(i)
33     mutex.release()  # 释放锁
34 
35 
36 if __name__ == '__main__':
37     mutex = Lock()  # 生成了一把锁
38     for i in range(10):
39         p = Process(target=run,args=(i,mutex))
40         p.start()
互斥锁的应用:抢票系统
在Windows操作系统中由于没有fork(linux操作系统中创建进程的机制),在创建子进程的时候会自动 import 启动它的这个文件,而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子进程的部分使用if __name__ ==‘__main__’ 判断保护起来,import 的时候  ,就不会递归运行了。

猜你喜欢

转载自www.cnblogs.com/yangjiaoshou/p/11329289.html