# 多进程 ### fork() Unix/Linux操作系统提供了一个`fork()`系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是`fork()`调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。 子进程永远返回`0`,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用`getppid()`就可以拿到父进程的ID。 `os`模块封装了常见的系统调用,其中就包括`fork`,可以在Python程序中轻松创建子进程 ```python import os print("Process (%s) start..."%os.getpid()) pid = os.fork() if pid == 0: print('I am child process (%s) and my parent is (%s).' % (os.getpid(), os.getppid())) else: print('I (%s) just created a child process (%s).' % (os.getpid(), pid)) ``` ### multiprocessing模块Process类 multiprocessing模块是跨平台版本的多进程模块。`multiprocessing`模块提供了一个`Process`类来代表一个进程对象。 ```python 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.') ``` 创建子进程时,只需要传入一个执行函数和函数的参数,创建一个`Process`实例,用`start()`方法启动,这样创建进程比`fork()`还要简单。 ### multiprocessing模块Pool类 如果要启动大量的子进程,可以用进程池(Pool)的方式批量创建子进程。 ```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("Waithing for all subprocesses done...") p.close() p.join() print('All subprocesses done.') ``` 对`Pool`对象调用`join()`方法会等待所有子进程执行完毕,调用`join()`之前必须先调用`close()`,调用`close()`之后就不能继续添加新的`Process`了。 请注意输出的结果,task `0`,`1`,`2`,`3`是立刻执行的,而task `4`要等待前面某个task完成后才执行,这是因为`Pool`的默认大小在我的电脑上是4,因此,最多同时执行4个进程。这是`Pool`有意设计的限制,并不是操作系统的限制。 ### 子进程 很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。`subprocess`模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。 如果子进程还需要输入,则可以通过`communicate()`方法输入。 ### 进程间通讯 进程间通信是通过`Queue`、`Pipes`等实现的。