Python中的多进程、多线程和协程 (4)

输出(Win下与Linux下相似):

main process id 18416 starts at 0.000004s start assigning tasks all tasks assigned; wait for son processes to finish son process id 10052 starts working on TaskNo.1 at 0.053483s with parameter 1, this process already executed ['init'] son process id 17548 starts working on TaskNo.2 at 0.040412s with parameter 1, this process already executed ['init'] son process id 10124 starts working on TaskNo.3 at 0.049992s with parameter 1, this process already executed ['init'] son process id 10124 ends working on TaskNo.3 at 1.054387s son process id 17548 ends working on TaskNo.2 at 1.044956s son process id 10052 ends working on TaskNo.1 at 1.062396s son process id 10124 starts working on TaskNo.4 at 1.055888s with parameter 1, this process already executed ['init', 'TaskNo.3'] son process id 10124 ends working on TaskNo.4 at 2.060094s all tasks finished at 2.443017s main process id 18416 ends at 2.444705s 在进程池中利用子进程的返回值 from multiprocessing import Pool import time def task(duration, base_time, task_name): time.sleep(duration) return f'{task_name} finished at {"%.6f" % (time.perf_counter()-base_time)}s' if __name__ == '__main__': base_time = time.perf_counter() pool = Pool(2) return_values = [] return_values.append(pool.apply(task, args=(1,base_time,'TaskNo.1_sync'))) print('at time {}, r_v is {}'.format(time.perf_counter() - base_time, return_values)) return_values.append(pool.apply_async(task, args=(2,base_time,'TaskNo.2_async'))) print('at time {}, r_v is {}'.format(time.perf_counter() - base_time, return_values)) pool.close() pool.join() print(f'all tasks finished at {"%.6f" % (time.perf_counter()-base_time)}s') assert return_values[1].ready() == True return_values[1] = return_values[1].get() # from ApplyResult to true return value print('results:', return_values) at time 1.2109459, r_v is ['TaskNo.1_sync finished at 1.027223s'] at time 1.2124976, r_v is ['TaskNo.1_sync finished at 1.027223s', <multiprocessing.pool.ApplyResult object at 0x0000016D24D79AC0>] all tasks finished at 3.258190s results: ['TaskNo.1_sync finished at 1.027223s', 'TaskNo.2_async finished at 3.041053s']

这里在pool.join()之后调用result.get(),所以可以立刻得到 子进程所执行的函数的返回值;如果在对应的子进程尚未return时就调用result.get(),则主进程会阻塞直到子进程返回,然后获取子进程所执行的函数的返回值。result.ready()返回一个bool,表示对应的子进程是否已经return。

此外,result.wait()会阻塞直到子进程返回,但不会获取返回值。

一个ApplyResult实例可以多次调用get(),即可以多次获取返回值。

详见 。

进程间通讯

可以认为,任何一个被跨进程传送的对象,在传送过程中都会被深拷贝。

Pipe from multiprocessing import Process, Pipe import time def send_through_pipe(conn, pipe_name, sender_name, content, base_time): print(sender_name, 'tries to send', content, 'through', pipe_name, 'at', '%.6f'%(time.perf_counter()-base_time)) conn.send(content) print(sender_name, 'successfully finishes sending at', '%.6f'%(time.perf_counter()-base_time)) def receive_from_pipe(conn, pipe_name, receiver_name, base_time): print(receiver_name, 'tries to receive content from', pipe_name, 'at', '%.6f'%(time.perf_counter()-base_time)) content = conn.recv() print(receiver_name, 'successfully receives', content, 'at', '%.6f'%(time.perf_counter()-base_time)) return content def task(conn, pipe_name, process_name, base_time): receive_from_pipe(conn, pipe_name, process_name, base_time) time.sleep(1) send_through_pipe(conn, pipe_name, process_name, 142857, base_time) if __name__ == '__main__': base_time = time.perf_counter() conn_A, conn_B = Pipe() # two endpoints of the pipe p1 = Process(target=task, args=(conn_B,'pipe','son',base_time)) p1.start() time.sleep(1) send_through_pipe(conn_A, 'pipe', 'main', ['hello','hello','hi'], base_time) # any object can be sent receive_from_pipe(conn_A, 'pipe', 'main', base_time) p1.join() son tries to receive content from pipe at 0.036439 main tries to send ['hello', 'hello', 'hi'] through pipe at 1.035570 main successfully finishes sending at 1.037174 main tries to receive content from pipe at 1.037318 son successfully receives ['hello', 'hello', 'hi'] at 1.037794 son tries to send 142857 through pipe at 2.039058 son successfully finishes sending at 2.040158 main successfully receives 142857 at 2.040441

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgdgd.html