python Pool与processpoolexecutor区别 processing和python什么关系_多线程


进程与线程

进程(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 Pool与processpoolexecutor区别 processing和python什么关系_多进程_02

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 Pool与processpoolexecutor区别 processing和python什么关系_python廖雪峰_03

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] 百度百科:进程