Python3基础-进程间通讯
multiprocessing包是Python中的多进程管理包。 与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。 该进程可以运行在Python程序内部编写的函数。 该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。 此外multiprocessing包中也有Lock/Event/Semaphore/Condition类
(这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。
所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境
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=('alvin',)) p_list.append(p) p.start() for i in p_list: p.join() print('end')
from multiprocessing import Process import time class MyProcess(Process): def __init__(self): super(MyProcess, self).__init__() #self.name = name def run(self): time.sleep(1) print ('hello', self.name,time.ctime()) if __name__ == '__main__': p_list=[] for i in range(3): p = MyProcess() p.start() p_list.append(p) for p in p_list: p.join() print('end')
构造方法: Process([group [, target [, name [, args [, kwargs]]]]]) group: 线程组,目前还没有实现,库引用中提示必须是None; target: 要执行的方法; name: 进程名; args/kwargs: 要传入方法的参数。 实例方法: is_alive():返回进程是否在运行。 join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。 start():进程准备就绪,等待CPU调度 run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。 terminate():不管任务是否完成,立即停止工作进程 属性: daemon:和线程的setDeamon功能一样 name:进程名字。 pid:进程号。
from multiprocessing import Process import time class MyProcess(Process): def __init__(self): super(MyProcess, self).__init__() #self.name = name def run(self): time.sleep(1) print ('hello', self.name,time.ctime()) if __name__ == '__main__': p_list=[] for i in range(3): p = MyProcess() p.daemon=True p.start() p_list.append(p) # for p in p_list: # p.join() print('end') ==================== 结果输出 end
from multiprocessing import Process import os import time def info(title): print("title:", title) print('parent process:', os.getppid()) print('process id:', os.getpid()) def f(name): info('function f') print('hello', name) if __name__ == '__main__': info('main process line') time.sleep(1) print("------------------") p = Process(target=info, args=('yuan',)) p.start() p.join()
输出结果如下:
title: main process line parent process: 13796 process id: 2624 ------------------ title: yuan parent process: 2624 process id: 13512
os.getpid()
- 功能:获取一个进程的PID值
- 返回值:返回当前进程的PID
os.getppid()
- 功能:获取父进程的PID值
- 返回值:返回父进程PID
os._exit(status)
- 功能:结束一个进程
- 参数:进程的终止状态(随便输一个整数,eg:0,代表结束状态)
sys.exit([status])
- 功能:退出进程
- 参数:
- 整数:表示退出状态
- 字符串:表示退出时,打印内容
############进程间通信
不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用多进程里的Queue来解决
Queues
使用方法跟threading里的queue差不多,注意在执行的时候,queue是一个备份,而不是原来的queue,不过实现了数据共享
#进程间通讯 from multiprocessing import Process, Queue #import queue def f(q,n): #q.put([123, 456, 'hello']) q.put(n*n+1) #print("q===is",q.get()) print("son process",id(q)) if __name__ == '__main__': q = Queue() #try: q=queue.Queue() print("main process",id(q)) #print("q ===is:",q.get()) for i in range(3): #print("i===",i) p = Process(target=f, args=(q,i)) '''实现主进程和子进程的同学,放入同一个队列中''' p.start() print("get的内容是",q.get()) print("get的内容是",q.get()) print("get的内容是",q.get())
Pipe管道
和队列的功能差不多,实现两个进程之前数据的传递
from multiprocessing import Process, Pipe def f(conn): conn.send([12, {"name":"yuan"}, 'hello']) response=conn.recv() print("response",response) print("q_ID2:", id(conn)) conn.close() if __name__ == '__main__': parent_conn, child_conn = Pipe() #管道会产生两个返回值 print("q_ID1:",id(child_conn)) p = Process(target=f, args=(child_conn,)) #创建一个子进程 p.start() print(parent_conn.recv()) # 收到 [12, {"name":"yuan"}, 'hello'] parent_conn.send("你好!") # 发送 您好! p.join()
Manager 管道
上面两种都是实现数据传递,并没有实现数据共享,即一个进程去更改另一个进程的数据
现在实现数据共享
可实现的数据类型很多:list、dict、Namespace、Locl、 RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array
写法1
from multiprocessing import Process, Manager def f(d, l,i): d[1] = '1' d['2'] = 2 l.append(i) # 追加一个i # print(l) if __name__ == '__main__': d = Manager().dict() # 生成一个字典,可在多个进程间共享和传递 l = Manager().list(range(5)) # 列表 print("初始字典",d) print("初始列表",l) p_list = [] # 进程列表 for i in range(10): p = Process(target=f, args=(d, l, i)) # 循环10次每次创建一个进程 p.start() p_list.append(p) # 加入进程列表里 for res in p_list: # 等所有进程结束 res.join() print(d) print(l)
写法2
from multiprocessing import Process, Manager def f(d, l,i): d[1] = '1' d['2'] = 2 l.append(i) # 追加一个i # print(l) if __name__ == '__main__': with Manager() as manager: d = manager.dict() l = manager.list(range(5)) print("初始字典",d) print("初始列表",l) p_list = [] # 进程列表 for i in range(10): p = Process(target=f, args=(d, l, i)) # 循环10次每次创建一个进程 p.start() p_list.append(p) # 加入进程列表里 for res in p_list: # 等所有进程结束 res.join() print(d) print(l)
执行结果如下:
初始字典 {} 初始列表 [0, 1, 2, 3, 4] {1: '1', '2': 2} [0, 1, 2, 3, 4, 0, 1, 3, 2, 4, 5, 6, 7, 8, 9]
浙公网安备 33010602011771号