zl程序教程

您现在的位置是:首页 >  后端

当前栏目

什么是进程池_进程池的实现

进程 实现 什么
2023-06-13 09:12:52 时间

大家好,又见面了,我是你们的朋友全栈君。

  今天学习了JIR、进程池和线程池

  GIL:Global Interpreter Lock

  全局解释器锁

    锁的作用:为了避免资源竞争造成数据错乱

  python程序的执行过程

    1.启动解释器进程 python.exe

    2.解析你的py文件并执行它

  每个py程序中殴斗必须有解释器参与 解释器其实就是一堆代码

  相当于多个线程要调用同一个解释器代码 共享意味着竞争 竞争就要出事

  给解释器加互斥锁

  python中内存管理依赖于 GC(一段用于回收内存的代码) 也需要一个线程

  除了你自己开的线程 系统还有一些内置线程 就算你的代码不会去竞争解释器 内置线程也可能会竞争

  所以必须加上锁

  当一个线程遇到了I/O 同时解释器也会自动解锁 去执行其他线程 cpu会切换到其他程序

  解释器加锁以后

    将导致所有线程只能并发 不能达到真正的并行 意味着同一时间只有一个CPU在处理你的线程给你的感觉是效率低

  代码执行有两种状态

  阻塞 i/o 失去CPU的执行权 (CPU等待IO完成)

  非阻塞 代码正常执行 比如循环一千万次 中途CPU可能切换 很快会回来  (CPU在计算)

  假如有32核CPU 要处理一个下载任务 网络速度慢 只有100kb/s 文件大小为1024kb

  如果你的代码中IO操作非常多 cpu性能不能直接决定你的任务处理速度

  在IO密集的程序中 CPU性能无法直接决定程序的执行速度 python就应该干这种活儿

  在计算密集的程序中 CPU性能可以直接决定程序的执行速度

  计算密集测试

from multiprocessing import Process import time #计算密集任务 def task1(): sum = 1 for i in range(10000000): sum *=i def task2(): sum = 1 for i in range(10000000): sum *=i def task3(): sum = 1 for i in range(10000000): sum *=i def task4(): sum = 1 for i in range(10000000): sum *=i def task5(): sum = 1 for i in range(10000000): sum *=i def task6(): sum = 1 for i in range(10000000): sum *=i if __name__ == '__init__': # 开始时间 st_time = time.time() # 多进程情况下 p1 = Process(target = task1) p2 = Process(target = task2) p3 = Process(target = task3) p4 = Process(target = task4) p5 = Process(target = task5) p6 = Process(target = task6) p1.start() p2.start() p3.start() p4.start() p5.start() p6.start() p1.join() p2.join() p3.join() p4.join() p5.join() p6.join() print(time.time()-st_time) ''' 1.05321354643464 '''

IO密集测试

from threading import Thread import time #计算密集任务 def task1(): time.sleep(3) def task2(): time.sleep(3) def task3(): time.sleep(3) def task4(): time.sleep(3) def task5(): time.sleep(3) def task6(): time.sleep(3) if __name__ == '__main__': #开始时间 st_time = time.time() #多线程情况下 t1 = Thread(target = task1) t2 = Thread(target = task2) t3 = Thread(target = task3) t4 = Thread(target = task4) t5 = Thread(target = task5) t6 = Thread(target = task6) t1.start() t2.start() t3.start() t4.start() t5.start() t6.start() t1.join() t2.join() t3.join() t4.join() t5.join() t6.join() print(time.time - st_time) ''' 3.0035946873164 '''

  二、进程池

  进程池就是一个装进程的容器

  为什么出现

    当进程很多的时候方便管理进程

  什么时候用?

    当并发量特别大的时候 例如双十一

    很多时候进程是空闲的 就让他进入进程池 让有任务处理时才从进程池取出来使用

  进程池使用

    ProcessPoolExecutor类

    创建时指定最大进程数  自动创建进程

    调用submit函数将任务提交到进程池中

    创建进程是在调用submit后发生的

  总结一下:

    进程池可以自动创建进程

    进程限制最大进程数

    自动选择一个空闲的进程帮你处理任务

  三、线程池

  和进程池差不多,使用的是ThreadPoolExcecutor类

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/166583.html原文链接:https://javaforall.cn