一 进程池与线程池

1.为什么需要进程池和线程池

基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:

服务端的程序运行在一台机器身上,一台机器性能是有极限的,不能无限开线程

服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪,于是我们必须对服务端开启的进程数或线程数加以控制,让机器在一个自己可以承受的范围内运行

2.线程池和进程池作用

这就是进程池或线程池的用途,例如进程池,就是用来存放进程的池子,本质还是基于多进程,只不过是对开启进程的数目加上了限制

进程池和线程池作用 ,限制开启的线程数据,进程数,保证机器在一个可承受范围,保持主机健康状态

3.什么时候开启线程和进程

计算机密集型程序用多进程,io密集型用多线程

介绍

  1. 官网:https://docs.python.org/dev/library/concurrent.futures.html
  2.  
  3. concurrent.futures模块提供了高度封装的异步调用接口
  4. ThreadPoolExecutor:线程池,提供异步调用
  5. ProcessPoolExecutor: 进程池,提供异步调用
  6. Both implement the same interface, which is defined by the abstract Executor class.


基本方法

  1. 1submit(fn, *args, **kwargs)
  2. 异步提交任务
  3.  
  4. 2map(func, *iterables, timeout=None, chunksize=1) func是函数,
  5. 取代for循环submit的操作
  6.  
  7. 3shutdown(wait=True)
  8. 相当于进程池的pool.close()+pool.join()操作
  9. wait=True,等待池内所有任务执行完毕回收完资源后才继续 默认不指定就是wait=True
  10. wait=False,立即返回,并不会等待池内的任务执行完毕
  11. 但不管wait参数为何值,整个程序都会等到所有任务执行完毕
  12. submitmap必须在shutdown之前
  13.  
  14. 4result(timeout=None)
  15. 取得结果
  16.  
  17. 5add_done_callback(fn)
  18. 回调函数

shutdown源码

  1. def shutdown(self, wait=True):
  2. with self._shutdown_lock:
  3. self._shutdown_thread = True

submit() 异步提交任务

什么是异步提交任务?

异步方式指的是 提交完任务后,不用再等着任务,执行拿到结果。提交完任务后就不管这个任务有没有起来,也不用等结果,

只负责提交任务

把任务扔到池子,池子帮忙开启线程或者进程

例如现在:池子收到10个任务,但池子限制4个进程或者线程,同一时间只能开4个进程 或者4个线程 只能执行4个任务,其他任务

只能等(阻塞),一个任务执行完,再给下一个等待任务执行,走一个进一个,池子就开启4个线程 ,4个线程把10个任务完成

二 进程池

用法

  1. from concurrent.futures import ProcessPoolExecutor
  2. import time
  3. import os
  4. import random
  5.  
  6. def task(name):
  7. print("name:%s pid:%s run" %(name, os.getpid()))
  8. time.sleep(random.randint(1,3))
  9.  
  10. if __name__ == "__main__":
  11. # 把进程池造出来,指定池的大小
  12. # 指定4个进程
  13. pool = ProcessPoolExecutor(4)
  14.  
  15. for i in range(1,11):
  16. pool.submit(task,"子进程%s" %i)
  17.  
  18. print("主")
  19.  
  20. '''

  21. name:子进程1 pid:8012 run
  22. name:子进程2 pid:14540 run
  23. name:子进程3 pid:16832 run
  24. name:子进程4 pid:5984 run
  25. name:子进程5 pid:14540 run
  26. name:子进程6 pid:5984 run
  27. name:子进程7 pid:8012 run
  28. name:子进程8 pid:14540 run
  29. name:子进程9 pid:16832 run
  30. name:子进程10 pid:8012 run
  31. '''

先打印主,提交任务是异步提交方式,提交完任务以后,什么都不要管,不管进程起来没有,也不打印结果,提交完就走,这就是异步提交

并且看到pid 开启4个pid,一直都是使用开启的4个pid,没有启动新的进程,一直都是刚开始的4个进程

主进程想等到 进程池所有任务都执行完后,主进程再执行, 相当于join方法

使用shutdown()

把往池里提交任务的入口关闭掉,不能提交任务到池子里,等到池子所有任务执行完,才能执行主进程,

三.为什么join要把池子入口关闭掉?

shutdown函数在维护一个计数器,把池子关闭,不能往池子提交任务,因为要明确统计现在池子拿到有几个任务,例如10个任务,

走一个任务,计数器就减1,直到计数器为0,池子入口就开放

  1. from concurrent.futures import ProcessPoolExecutor
  2. import time
  3. import os
  4. import random
  5.  
  6. def task(name):
  7. print("name:%s pid:%s run" %(name, os.getpid()))
  8. time.sleep(random.randint(1,3))
  9.  
  10. if __name__ == "__main__":
  11. # 把进程池造出来,指定池的大小
  12. # 指定4个进程
  13. pool = ProcessPoolExecutor(4)
  14.  
  15. for i in range(1,11):
  16. pool.submit(task,"子进程%s" %i)
  17.  
  18. pool.shutdown()
  19. print("主")
  20.  
  21. '''
  22. name:子进程1 pid:17744 run
  23. name:子进程2 pid:18208 run
  24. name:子进程3 pid:12440 run
  25. name:子进程4 pid:19396 run
  26. name:子进程5 pid:18208 run
  27. name:子进程6 pid:12440 run
  28. name:子进程7 pid:18208 run
  29. name:子进程8 pid:17744 run
  30. name:子进程9 pid:19396 run
  31. name:子进程10 pid:12440 run

  32. '''

三 线程池

用法

  1. ProcessPoolExecutor换成ThreadPoolExecutor,其余用法全部相同
  1. from concurrent.futures import ThreadPoolExecutor
  2. import time
  3. import os
  4. import random
  5.  
  6. def task(name):
  7. print("name:%s pid:%s run" %(name, os.getpid()))
  8. time.sleep(random.randint(1,3))
  9.  
  10. if __name__ == "__main__":
  11. # 把进程池造出来,指定池的大小
  12. # 指定4个进程
  13. pool = ThreadPoolExecutor(4)
  14.  
  15. for i in range(1,11):
  16. pool.submit(task,"子线程%s" %i)
  17.  
  18. pool.shutdown()
  19. print("主")
  20.  
  21. '''
  22. name:子线程1 pid:13736 run
  23. name:子线程2 pid:13736 run
  24. name:子线程3 pid:13736 run
  25. name:子线程4 pid:13736 run
  26. name:子线程5 pid:13736 run
  27. name:子线程6 pid:13736 run
  28. name:子线程7 pid:13736 run
  29. name:子线程8 pid:13736 run
  30. name:子线程9 pid:13736 run
  31. name:子线程10 pid:13736 run

  32. '''

map方法

  1. executor.map(task,range(1,12)) #map取代了for+submit
  1.  

python 并发编程 进程池与线程池的更多相关文章

  1. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  2. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  3. [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ...

    [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ... 摘要 介绍 Java 并发包里的几个主要 ExecutorService . 正文 ...

  4. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  5. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  6. Java并发编程:4种线程池和缓冲队列BlockingQueue

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池.使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动 ...

  7. 并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项

    并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 线程池的缘由 java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的 ...

  8. Java并发编程的艺术(十)——线程池(1)

    线程池的作用 减少资源的开销 减少了每次创建线程.销毁线程的开销. 提高响应速度 每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度. 提高线程的可管理性 线程是一种稀缺资 ...

  9. python并发编程-进程池线程池-协程-I/O模型-04

    目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...

随机推荐

  1. IPC 进程间通信方式——共享内存

    共享内存 共享内存区域是被多个进程共享的一部分物理内存. 多个进程都可以把共享内存映射到自己的虚拟空间.所有用户空间的进程要操作共享内存,都要将其映射到自己的虚拟空间,通过映射的虚拟内存空间地址去操作 ...

  2. RFID-RC522射频

    与Arduino的接线方法: 米其林编程:

  3. linux运维、架构之路-K8s应用

    一.Deployment         k8s通过各种Controller管理Pod的生命周期,为了满足不同的业务场景,k8s提供了Deployment.ReplicaSet.DaemonSet.S ...

  4. C/C++数据类型判断与转换

    最近总想着写一些通用的代码,然集中收纳到自己的私人库中去,这些代码期望能与公司基础数据结构无关.然而这比较难,因为无论如何,必需要用到一些结构 化的东西,这些与基础引擎等有关,必需极度抽象才可以做到层 ...

  5. socket认证客户端链接合法性

    服务器端: #_*_coding:utf-8_*_ __author__ = 'Linhaifeng' from socket import * import hmac,os secret_key=b ...

  6. AtCoder4351 Median of Medians 二分, 树状数组

    题目大意 定义一个从小到大的数列的中位数为第 $ \frac{n}{2}+1 $ 项.求一个序列的所有连续子序列的中位数的中位数. $ (n \leqslant 100000)$ 问题分析 由于\(n ...

  7. 设置centos7界面语言为中文

    1.在终端中输入命令 vim ~/.bashrc 来编辑“.bashrc”文件 2.在最后添加“ export LANG="zh_CN.UTF-8"  ” 3.执行 sudo sh ...

  8. 剑指offer-Q60 n个骰子的点数

    python版本代码 g_maxValue = 6 # 单个骰子最大的点数 def PrintProbability(number): ''' :param number: 骰子的个数 :return ...

  9. Js基础知识(二) - 原型链与继承精彩的讲解

    作用域.原型链.继承与闭包详解 注意:本章讲的是在es6之前的原型链与继承.es6引入了类的概念,只是在写法上有所不同,原理是一样的. 几个面试常问的几个问题,你是否知道 instanceof的原理 ...

  10. 对于Java培训出身的同学,接下来该怎么学习技术?

    首先恭喜从培训班出来找到工作的同学,确实挺不容易的,4个月的培训,每天从早上9点到晚上9点,也是996,主要的活动地方就是宿舍和教室, 让我现在也去培训,我估计还熬不下来. 尤其是对于从小白开始的同学 ...