进程和线程
每一个正在运行的程序都可以看作是一个进程,比如你打开了一个浏览器就是启动了一个浏览器进程,打开了QQ就是启动了一个QQ进程,打开两个QQ就是启动了两个QQ进程。
每个进程至少要干一件事,有的进程还不止干一件事,比如word文档,在你打字的同时,word程序本身还在进行拼写检查,字数统计等事情。在一个进程内部,要同时干很多不同的事情,就需要同时运行多个”子任务”,这些”子任务”称为线程。
multiprocessing
由于Windows上无法调用fork,所以需要引入multiprocessing这个多进程模块,multiprocessing模块提供了一个Process类来表示一个进程对象。
1 | import os |
执行结果
1 | Parent process 12704. |
start()方法用于启动一个子进程,join()方法可以等待子进程结束执行下一步。
Pool
1 | Signature: Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None) |
Pool中提供了以下几种方法
1 | apply() |
apply
1 | Signature: pool.apply(func, args=(), kwds={}) |
apply函数主要用于传递不定参数,主线程会被阻塞到函数执行结束。也就是说只有执行完了apply里面的内容之后,才会执行主函数的内容。
apply_async
1 | Signature: pool.apply_async(func, args=(), kwds={}, callback=None, error_callback=None) |
apply_async为异步非阻塞的,就是说不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。
subprocess
subprocess模块可以启动一个子进程,然后控制其输入和输出。
进程间通信
进程之间是需要通信的,python的multiprocessing模块封装了很多操作系统底层进程通信机制,提供了Queue
Pipes等多种方式来交换数据。
1 | from multiprocessing import Process,Queue |
Queue模块主要是保证线程安全使用的。
基本FIFO队列class Queue.Queue(maxsize=0)
即先进先出,如果参数为0或小于0,代表队列大小没有限制。
在Linux/Unix下,可以使用fork()调用实现多进程,
要实现跨平台的多进程,可以使用multiprocessing模块,
进程间通信是通过queue、pipes实现的。