文章目录
- 各个进程之间有什么特点
- 父进程和子进程的关系
- join同步控制
Process属于multiprocess中的一个类
import os
from multiprocessing import Process
def func():print('子进程',os.getpid(), os.getppid())
if __name__ == '__main__': print('主进程', os.getpid(), os.getppid())p = Process(target = func) p.start()
运行结果
主进程 14668 11392
子进程 7616 14668
为什么要写if __name__ == '__main__':
各个进程之间有什么特点
- 异步
- 数据隔离
数据隔离问题:进程直接的数据是不同的数据隔离问题:进程直接的数据是不同的
import os
import time
from multiprocessing import Process
count = 100
def func():global countcount -= 1print('子进程:', count)
if __name__ == '__main__':print('主进程', os.getpid(), os.getppid())p = Process(target=func)p.start()time.sleep(2)print('主进程:', count)
运行结果
主进程 14708 11392
子进程: 99
主进程: 100
import os
import time
from multiprocessing import Processcount = 100def func():global countcount -= 1print('子进程__name__:', __name__)print('>>>',__name__)if __name__ == '__main__':print('主进程', os.getpid(), os.getppid())p = Process(target=func)print('启动子进程')p.start()print('结束子进程')
运行结果
>>> __main__
主进程 7148 11392
启动子进程
结束子进程
>>> __mp_main__
子进程__name__: __mp_main__
父进程和子进程的关系
父进程只负责通知操作系统启动子进程
接下来的工作由操作系统接手,父进程继续执行
父进程执行完毕后并不会直接结束程序,
而是会等待所有的子进程都执行完毕之后才结束
父进程要负责回收子进程的资源。也就是告诉操作系统,子进程全部执行完毕,通知操作系统子进程全部执行完毕,叫操作系统释放命名空间或把变量清空等。只有主进程有权限通知操作系统的级别。
from multiprocessing import Process
import time
def f(name):time.sleep(1)print('hello', name, time.ctime())
if __name__ == '__main__':p_list = []for i in range(3):p = Process(target=f, args=('laura',))p_list.append(p)p.start()for i in p_list:i.join()print('end')
运行结果:
hello laura Sat Sep 22 11:21:47 2018
hello laura Sat Sep 22 11:21:47 2018
hello laura Sat Sep 22 11:21:47 2018
end
实例:
原生socket写并发程序
server端
import socketsk = socket.socket()
sk.bind(('127.0.0.1', 9000))
sk.listen()
while True: conn, addr = sk.accept() while True: conn.send(b'hello')print(conn.recv(1024))from multiprocessing import Processdef communicate(conn):while True:conn.send(b'hello')print(conn.recv(1024))if __name__ == '__main__':sk = socket.socket()sk.bind(('127.0.0.1', 9000))sk.listen()while True: conn, addr = sk.accept() Process(target=communicate, args=(conn,)).start()
client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))
while True:print(sk.recv(1024)) sk.send(b'bye')
join同步控制
join属于Process类中的一个方法
模拟十个进程分别发送十封邮件
import time
import random
from multiprocessing import Process
def func(index):time.sleep(random.random()) print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':for i in range(10):Process(target=func, args=(i, )).start() print('10个邮件已经发送完毕')
运行结果
10个邮件已经发送完毕
第4个邮件已经发送完毕
第0个邮件已经发送完毕
第8个邮件已经发送完毕
第2个邮件已经发送完毕
第7个邮件已经发送完毕
第9个邮件已经发送完毕
第5个邮件已经发送完毕
第1个邮件已经发送完毕
第3个邮件已经发送完毕
第6个邮件已经发送完毕
由于主进程和子进程完全异步,所以同时打印出来了,如图
可我要的结果是子进程全部执行完了再打印这句话。
Procee类中的join方法能够帮助我们知道子进程是什么时候结束的。作用:阻塞直到p进程执行完毕就结束阻塞。
用join方法实现同步控制
import time
import random
from multiprocessing import Process
def func(index):time.sleep(random.randint(1, 3)) print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':p = Process(target=func, args=(1, ))p.start()p.join()print('1个邮件已经发送完毕')
运行结果
第1个邮件已经发送完毕
1个邮件已经发送完毕
现在让十个进程异步发邮件,所有进程发完邮件后,才打印所有邮件发送完毕。相当于主进程和n个子进程同步了。
join在哪个进程下面就会在等待哪个进程。
import time
import random
from multiprocessing import Processdef func(index):time.sleep(random.random())print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':p_list = []for i in range(10):p = Process(target=func, args=(i, ))p.start()p_list.append(p)for p in p_list:p.join() print('10个邮件已经发送完毕')
运行结果
第2个邮件已经发送完毕
第4个邮件已经发送完毕
第1个邮件已经发送完毕
第9个邮件已经发送完毕
第3个邮件已经发送完毕
第6个邮件已经发送完毕
第7个邮件已经发送完毕
第5个邮件已经发送完毕
第8个邮件已经发送完毕
第0个邮件已经发送完毕
10个邮件已经发送完毕
例:输出资源,屏幕为进程间共享资源时。
from multiprocessing import Process, Lock
import time
def f(l, i):l.acquire()time.sleep(1) print('hello world %s' % i)l.release()if __name__ == '__main__':print(time.time())lock = Lock()list1 = []for num in range(10):p = Process(target=f, args=(lock, num))p.start()list1.append(p)for i in list1:i.join()print(time.time())
运行结果
1537682507.537764
hello world 0
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
hello world 6
hello world 8
hello world 7
hello world 9
1537682517.8930845