当前位置:   article > 正文

Python高阶语法--进程池_python 进程池

python 进程池

紧接着上篇进程后,今天继续更新进程池相关介绍
上篇介绍过,系统不可能无限的创建进程,它本身会收到CPU和内存的约束,这时候可以通过进程池来提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间,另外进程池还可以节省内存空间。下面进入正篇:

什么是进程池
进程池顾名思义就是一个装进程的池子,可以提供指定数量的进程给用户使用,即当有新的请求提交到进程池中时,如果池未满,则会创建一个新的进程用来执行该请求;反之,如果池中的进程数已经达到规定最大值,那么该请求就会等待,只要池中有进程空闲下来,该请求就能得到执行。

为什么要使用进程池
提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间;
节省内存空间。

如何创建进程池

import multiprocessing
pool=multiprocessing.Pool(num)   #num代表进程池中的最大进程数
  • 1
  • 2

进程池Pool的常用方法及参数
参数:

processes  : int类型参数,代表进程池最大进程数
  • 1

方法:

apply(func=func)    #同步阻塞式,必须要等待前一个子进程执行完后面才会继续执行
  • 1
apply_async(func=func)  #异步非阻塞式,不用等待当前运行的子进程执行完毕,随时根据系统调度来进行进程切换
  • 1
补充:
同步和异步的区别:
同步:指一个进程在执行某个请求的时候,必须要到收到对方返回的信息才继续执行下去;
异步:指进程在执行某个请求时,不管其他的进程的状态,这个进程就执行后续操作;当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率

例如:打电话就是同步通信,发信息就是异步通信。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

同步:

同步阻塞式
import multiprocessing
import os, time


def work():
    print(f'进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    time.sleep(1)


if __name__ == '__main__':
    print('--------开始主进程------------')
    print(f'主进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    start_time = time.time()
    pool = multiprocessing.Pool(4)
    for i in range(1, 6):
        pool.apply(func=work)
    pool.close()
    pool.join()
    time.sleep(5)
    end_time = time.time()
    print(f'----------主进程结束,耗时:{end_time - start_time}-------------------')

####运行输出结果:
#--------开始主进程------------
#主进程名MainProcess,进程号15460
#进程名SpawnPoolWorker-1,进程号19208
#进程名SpawnPoolWorker-2,进程号7112
#进程名SpawnPoolWorker-3,进程号19112
#进程名SpawnPoolWorker-4,进程号7244
#进程名SpawnPoolWorker-1,进程号19208
#----------主进程结束,耗时:10.170766353607178-------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

异步:

#异步非阻塞式
import multiprocessing
import os, time


def work():
    print(f'进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    time.sleep(1)


if __name__ == '__main__':
    print('--------开始主进程------------')
    print(f'主进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    start_time = time.time()
    pool = multiprocessing.Pool(4)
    for i in range(1, 6):
        pool.apply_async(func=work)
    pool.close()
    pool.join()
    time.sleep(5)
    end_time = time.time()
    print(f'----------主进程结束,耗时:{end_time - start_time}-------------------')
#####运行输出结果:
#--------开始主进程------------
#主进程名MainProcess,进程号11252
#进程名SpawnPoolWorker-1,进程号14152
#进程名SpawnPoolWorker-2,进程号6236
#进程名SpawnPoolWorker-4,进程号18728
#进程名SpawnPoolWorker-3,进程号18932
#进程名SpawnPoolWorker-4,进程号18728
#----------主进程结束,耗时:7.170076608657837-------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
'
运行

对比上面两段代码,明显可以看到异步的执行效率远高于同步,故而异步是我们的首选。
python官方指导文档也有关于这块的介绍:

官方文档关于apply()的介绍
Call func with arguments args and keyword arguments kwds. It blocks until the result is ready. Given this blocks, apply_async() is better suited for performing work in parallel. Additionally, func is only executed in one of the workers of the pool.
  • 1
  • 2
terminate()  #立刻关闭进程池
join() #主进程等待所有子进程执行完毕,必须在close或terminete之后
close() #等待所有进程结束才关闭线程池
  • 1
  • 2
  • 3

terminate使用:

import multiprocessing
import os, time


def work():
    print(f'进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    time.sleep(1)


if __name__ == '__main__':
    print('--------开始主进程------------')
    print(f'主进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    start_time = time.time()
    pool = multiprocessing.Pool(4)
    for i in range(1, 6):
        pool.apply_async(func=work)
    time.sleep(1)
    pool.terminate()
    pool.join()
    end_time = time.time()
    print(f'----------主进程结束,耗时:{end_time - start_time}-------------------')
####运行结果输出:
#--------开始主进程------------
#主进程名MainProcess,进程号17872
#进程名SpawnPoolWorker-1,进程号17280
#进程名SpawnPoolWorker-2,进程号8600
#进程名SpawnPoolWorker-3,进程号1016
#进程名SpawnPoolWorker-4,进程号7184
#----------主进程结束,耗时:1.050588607788086-------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

close()使用:

import multiprocessing
import os, time


def work():
    print(f'进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    time.sleep(1)


if __name__ == '__main__':
    print('--------开始主进程------------')
    print(f'主进程名{multiprocessing.current_process().name},进程号{os.getpid()}')
    start_time = time.time()
    pool = multiprocessing.Pool(4)
    for i in range(1, 6):
        pool.apply_async(func=work)
    time.sleep(1)
    pool.close()
    pool.join()
    end_time = time.time()
    print(f'----------主进程结束,耗时:{end_time - start_time}-------------------')

#####运行结果输出:
#--------开始主进程------------
#主进程名MainProcess,进程号19360
#进程名SpawnPoolWorker-1,进程号17640
#进程名SpawnPoolWorker-2,进程号18588
#进程名SpawnPoolWorker-4,进程号18404
#进程名SpawnPoolWorker-3,进程号18376
#进程名SpawnPoolWorker-1,进程号17640
#----------主进程结束,耗时:2.1518847942352295-------------------
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
'
运行

通过terminal和close两段代码对比可以明显看出两者差异

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/860766
推荐阅读
相关标签
  

闽ICP备14008679号