进程与线程
进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1]。比如,打开一个word文件就是启动了一个word进程。
线程(thread)是进程内的子任务。比如word中可以进行编辑、拼写检查和打印等子任务。
我们目前的操作系统都是多任务的操作系统,多任务的实现方式[2]:
- 多进程
- 多线程
- 多进程 + 多线程
多进程:multiprocessing模块
Unix Like[3]系统中,可以用python中os模块的os.fork()方法,为当前进程创建一个“子进程”[4],当前进程称作“父进程”。
说的简单一点,就是当你调用os.fork()以后,会有两个进程运行这之后的代码,它们的pid(process id)不一样。
由于一些玄学或是一些不知名的原因,用这个方法以后,我心爱的mbp风扇呼呼响,所以只好作罢。
multiprocessing模块比os.fork()好用的多,这个模块也可以用于创建多进程。而且它有一些基本的对象如Queue等支持进程间通信。下面主要讨论用multiprocessing模块怎么实现多进程。
- 创建一个子进程
multiprocessing.Process类可以初始化一个子进程,target参数传入子进程函数。
from multiprocessing import Process
import os, time
# 子进程函数
def sub_process():
print('Sub Process (%s) Start!' % os.getpid())
for i in reversed(range(3)):
time.sleep(1)
print(i+1)
time.sleep(1)
print('Over!')
print('Main Prcess (%s) Start!' % os.getpid())
for i in reversed(range(3)):
time.sleep(1)
print(i+1)
time.sleep(1)
print('GO!')
time.sleep(1)
p = Process(target=sub_process)
# 子进程开始
p.start()
# 等待子进程结束
p.join()
代码执行的效果如下:
python创建一个进程https://www.zhihu.com/video/1060526231002390528
- 创建多个子进程
multiprocessing.Pool类可以创建一个进程池,进程吃通过调用apply_async函数来创建一个新的进程。
from multiprocessing import Pool
import os,time
def sub_process(n):
time.sleep(1)
print('Process (%s) is running!' % os.getpid())
# 指定同时运行的进程数
p = Pool(4)
for i in range(5):
p.apply_async(sub_process,args=(i+1,))
# 不能继续添加进程了
p.close()
p.join()
python进程池https://www.zhihu.com/video/1060539118525841408
可以清晰的看见,我们指定了同时运行的进程数为4,因此最开始添加的4个进程都停了1秒就有了输出,而最后一个进程在1秒以后才有输出。
多线程:threading模块
多线程相比于多进程的好处是能更快一点,但是也没快多少。python中常用threading模块实现多线程。
import threading, time
def thread():
print('%s is running' % threading.current_thread().name)
print('%s is running' % threading.current_thread().name)
time.sleep(1)
t = threading.Thread(target=thread, name='Sub_Thread')
t.start()
t.join()
后记
当然多进程和多线程的内容远不止这些,其他的还有进程间通信、线程中的锁、ThreadLocal等。由于立下了一天写一篇文章的flag,如果一开始就把这件事搞的非常复杂就会损失做这个事的乐趣。所以我打算偷点懒,少点写,以后再增加工作量~
Ref.
[1] 百度百科:进程