多进程
大约 3 分钟
Python基础系列内容为学习廖雪峰老师Python3教程的记录,廖雪峰老师官网地址:廖雪峰Python3教程
基本解释:对于操作系统来说,一个任务就是一个进程
Process
,有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程Thread
。执行多任务:Python内执行多任务的方式有三种,即:
多线程
、多进程
、多进程+多线程
多进程
multiprocessing
:Python实现多进程在Linux
等系统上提供系统调用fork()
函数,而在Windows
系统上提供了Process
来提供多进程使用from multiprocessing import Process import os # 子进程要执行的代码 def run_proc(name): print('Run child process %s (%s)...' % (name, os.getpid())) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Process(target=run_proc, args=('test',)) print('Child process will start.') p.start() p.join() print('Child process end.')
运行上述代码:
Parent process 8072. Child process will start. Run child process test (14316)... Child process end. [Finished in 0.6s]
如果要启动大量进程同时执行,可以使用Python提供的进程池:
from multiprocessing import Pool import os, time, random def long_time_task(name): print('Run task %s (%s)...' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() p.join() print('All subprocesses done.')
子进程
很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。
subprocess
模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。下面的代码演示了调用命令
nslookup www.python.org
的结果,这跟在命令行直接输入该命令效果是一样:import subprocess print('nslookup www.python.org') r = subprocess.call(['nslookup', 'www.python.org']) print('Exit code:', r)
结果如下:
nslookup www.python.org Non-authoritative answer: Server: localhost Address: 127.0.0.1 Name: dualstack.python.map.fastly.net Address: 151.101.72.223 Aliases: www.python.org Exit code: 0
如果子进程还需要输入,则可以通过
communicate()
方法来输入:import subprocess print('nslookup') p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = p.communicate(b'set q=mx\npython.org\nexit\n') print(output.decode('utf-8')) print('Exit code:', p.returncode)
结果:
nslookup Default Server: localhost Address: 127.0.0.1 > > Server: localhost Address: 127.0.0.1 > Exit code: 0
进程间通信
Process
之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing
模块包装了底层的机制,提供了Queue
、Pipes
等多种方式来交换数据。我们以
Queue
为例,在父进程中创建两个子进程,一个往Queue
里写数据,一个从Queue
里读数据:from multiprocessing import Process,Queue import os,time,random # 写数据 def write(q): print("Process to write:%s"%os.getpid()) for value in ['A','B','C']: print('Put %s to queue...'%value) q.put(value) time.sleep(random.random()) # 读数据 def read(q): print("Process to read: %s"%os.getpid()) while True: value=q.get(True) print('Get %s from queue.'%value) if __name__=="__main__": q=Queue() pw=Process(target=write,args=(q,)) pr=Process(target=read,args=(q,)) pw.start() pr.start() pw.join() pr.terminate()
结果:
Process to read: 16104 Process to write:18016 Put A to queue... Get A from queue. Put B to queue... Get B from queue. Put C to queue... Get C from queue.