1.开启子进程的两种方式
1 from multiprocessing import Process
2 import time
3
4 def task(name):
5 print('%s is running'%name)
6 time.sleep(2)
7 print('%s is down'%name)
8
9 if __name__ == "__main__":
10 # p = Process(target=task,kwargs={'name':'alice'})
11 p = Process(target=task,args=('alice',))
12 p.start()
13
14 print('主')
方式一
1 from multiprocessing import Process
2 import time
3
4 class MyProcess(Process):
5 def __init__(self,name):
6 super().__init__()
7 self.name = name
8
9 def run(self):
10 print('%s is running'%self.name)
11 time.sleep(2)
12 print("%s is down"%self.name)
13
14 if __name__ == "__main__":
15 p = MyProcess('子进程1')
16 p.start()
17
18 print('主')
方式二
2.查看pid
1.os.getpid()
2.os.getppid()
1 from multiprocessing import Process
2 import time
3 import os
4
5 def task(name):
6 print('%s is running'%name,os.getpid(),os.getppid())
7 time.sleep(2)
8 print('%s is down'%name)
9
10 if __name__ == "__main__":
11 p = Process(target=task,args=('子进程1',))
12 p.start()
13
14 print('主',os.getpid(),os.getppid())
查看pid
3.僵尸进程/孤儿进程
父进程一直不死,子进程变成了僵尸进程一直占着pid;有害
孤儿进程,父进程先死了,linux中最大的父进程init进程会回收孤儿进程的pid
4.Process对象的其他属性或方法
p = Process(target=task,kwargs={'name':'子进程1'})
p = Process(target=task,name='sub-process',args=('子进程1',))
0. p.start() # 只是给os发了一个信号,调用 p.run()
1. p.join() # 等待子进程运行完成
2. p.pid # 查看子进程的pid
3. p.is_alive() # 查看子进程是否还活着
4. p.name # 查看子进程的name
5. p.terminate() # 给os发个信号,杀死子进程,信号,需要时间处理
多个子进程p.join()是并发执行,遇到io切 5s 多
多个子进程p1.start() p1.join() 是串行执行 10s
1 from multiprocessing import Process
2 import os
3 import time
4
5 def task(name,n):
6 print('%s is running'%name,os.getpid(),os.getppid())
7 time.sleep(n)
8 print('%s is down'%name)
9
10 if __name__ == "__main__":
11 start = time.time()
12 p1 = Process(target=task,name='sub-process',args=('子进程1',5))
13 p2 = Process(target=task,args=('子进程2',3))
14 p3 = Process(target=task,args=('子进程3',2))
15 p_l = [p1,p2,p3] # 并行 5s 多
16 for p in p_l:
17 p.start()
18 print(p1.is_alive()) # True
19 p1.terminate() # 给os 发个信号,杀死子进程,需要时间
20 time.sleep(2)
21 print(p1.is_alive()) # False
22 print(p1.name)
23 print(p2.name)
24 for p in p_l:
25 p.join()
26
27 print(p1.is_alive()) # False
28 print(p1.name)
29 print(p2.name)
30 print(p1.pid)
31
32 # p1.start() # 串行 10s 多
33 # p1.join()
34 # p2.start()
35 # p2.join()
36 # p3.start()
37 # p3.join()
38
39 end = time.time()
40 print('主',end-start) # 用时5s多,说明是 并发执行
41
42 # print(p.pid)
43 # 这里任然得到了子进程的pid 说明子进程变成了 僵尸进程
44 # 主进程结束了,基于它的子进程才会结束,即僵尸进程的pid才会被回收
Process对象的其他属性或方法
5.守护进程
开进程的目的:并发任务,假设任务在主进程死后没意义存在了,就设为守护进程
守护进程:
1. p.daemon = True
2. 主进程结束时,守护进程也结束了
3. 守护进程一定要在p.start()前设置
4. 不允许在守护进程内在开子进程,没意义
1 from multiprocessing import Process
2 import time
3
4 def task(name):
5 print('%s is running'%name)
6 time.sleep(2)
7 print('%s is down'%name)
8 p = Process(target=time.sleep,args=(3,))
9 p.start()
10
11 if __name__ == "__main__":
12 p = Process(target=task,args=('子进程1',))
13 p.daemon = True
14 p.start()
15
16 print('主')
17
18 # 思考下列代码的执行结果有可能有哪些情况?为什么?
19 from multiprocessing import Process
20 import time
21
22 def foo():
23 print(123)
24 time.sleep(1)
25 print("end123")
26
27 def bar():
28 print(456)
29 time.sleep(3)
30 print("end456")
31
32 if __name__ == '__main__':
33 p1=Process(target=foo)
34 p2=Process(target=bar)
35
36 p1.daemon=True # 主进程死后,代码执行完毕,守护进程就死了
37 p1.start()
38 p2.start()
39 print("main-------") # 只要这里一运行,守护进程就完了
40 """
41 main-------
42 456
43 end456
44 """
守护进程
6.互斥锁:
进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱
如何控制,就是加锁处理:
互斥锁的原理,就是把并发改成串行,降低了效率,但保证了数据安全不错乱。保证了多个进程修改一块数据时,一个一个修改,不错乱。
1 # 并发运行,效率高,但竞争同一打印终端,带来了打印错乱
2 # 由并发变成了串行,牺牲了运行效率,但避免了竞争
3 from multiprocessing import Process,Lock
4 import time
5 import os
6
7 def task(lock):
8 lock.acquire()
9 print('%s is running'%os.getpid())
10 time.sleep(2)
11 print('%s is done'%os.getpid())
12 lock.release()
13
14 if __name__ == "__main__":
15 lock = Lock()
16 for i in range(3):
17 p = Process(target=task,args=(lock,))
18 p.start()
互斥锁
7.互斥锁的应用:
模拟抢票
加锁处理:购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全
with mutex:
get(name)
等价于:
mutex.acquire()
mutex.release()
1 # 文件db.txt的内容为:{"count":1}
2 # 注意一定要用双引号,不然json无法识别
3 import json
4 import time
5 from multiprocessing import Process,Lock
6
7 def search(name):
8 with open('db.txt','r',encoding='utf-8') as f:
9 dic =json.load(f)
10 time.sleep(1)
11 print('