一、进程池和线程池

当被操作对象数目不大时,我们可以手动创建几个进程和线程,十几个几十个还好,但是如果有上百个上千个。手动操作麻烦而且电脑硬件跟不上,可以会崩溃,此时进程池、线程池的功效就能发挥了。我们可以通过维护一个进程池、线程池来控制进程数目和线程数目。在保证计算机硬件安全的情况下最大限度的利用计算机,池其实是降低了程序的运行效率,但是保证了计算机硬件的安全。

注意点:在使用进程池、线程池,Pool可以提供指定数量的进程,线程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程,线程用来执行该请求,但如果池中的进程,线程数量已经达到规定的最大值,那么该请求就会等待,直到池中有进程,线程结束,就重新使用进程池、线程池中的进程,线程。

池子中创建的进程/线程创建一次就不会再创建了,至始至终都是使用最初的那几个,这样的话节省了反复开辟进程/线程的资源(******)

主要方法:

pool.submit(task,1)     #朝池子中提交任务  异步提交    task是函数,1是task的参数
pool.shutdown() #关闭池子 等待池子中所有任务执行完毕之后才会往下运行代码

线程池和进程池创建的方法一样只是导入的模块不一样

回调函数add_done_callback,我们可以把耗时间(IO操作)的任务放在进程池中,然后指定回调函数(主进程负责执行),这样主进程在执行回调函数时就省去了IO的过程,直接拿到的是任务的结果。

异步回调机制:当异步提交的任务有返回结果之后,会自动触发回调函数的执行。

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time
import os # pool = ThreadPoolExecutor(5) 创建线程池 # 括号内可以传参数指定线程池内的线程个数 也可以不传 不传默认是当前所在计算机的cpu个数乘5
pool = ProcessPoolExecutor() 创建进程池 # 默认是当前计算机cpu的个数 def task(n):
print(n,os.getpid()) # 查看当前进程号
time.sleep(2)
return n**2 def call_back(n):
print('拿到了异步提交任务的返回结果:',n.result()) #submit提交任务返回值,需要result才能获取结果 """
异步回调机制:当异步提交的任务有返回结果之后,会自动触发回调函数的执行 """
if __name__ == '__main__':
for i in range(20):
pool.submit(task,i).add_done_callback(call_back) # 提交任务的时候 绑定一个回调函数 一旦该任务有结果 立刻执行对于的回调函数 #submit提交任务task函数,当有返回值时,立刻把返回值传入回调函数

二、协程

协程就是单线程下实现并发 ,协程:完全是程序员自己想出来的一个名词

程序员通过自己代码检测程序中的IO操作,一旦遇到IO自己通过代码切换,给操作系统的感觉是你这个线程没有任何的IO,从而保证程序在运行态和就绪态来回切换,提升代码的运行效率。

切换+保存状态就一定能够提升效率吗???

当你的任务是io密集型的情况下    会提升效率

当你的任务是计算密集型时       会降低效率

spawn会自动帮你检测任务有没有I/O,碰到I/O就切换

from gevent import monkey;monkey.patch_all()  # 由于该模块经常被使用 所以建议写成一行
from gevent import spawn
import time
"""
注意gevent模块没办法自动识别time.sleep等io情况
需要你手动再配置一个参数 monkey
""" def heng():
print("哼")
time.sleep(2)
print('哼') def ha():
print('哈')
time.sleep(3)
print('哈') def heiheihei():
print('嘿嘿嘿')
time.sleep(5)
print('嘿嘿嘿') start = time.time()
g1 = spawn(heng)
g2 = spawn(ha) # spawn会检测所有的任务
g3 = spawn(heiheihei)
g1.join()
g2.join()
g3.join()
print(time.time() - start) #结果


嘿嘿嘿


嘿嘿嘿
5.012551546096802

三、TCP单线程实现并发

服务端

from gevent import monkey;monkey.patch_all()
import socket
from gevent import spawn server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5) def talk(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0:break
print(data.decode('utf-8'))
conn.send(data.upper())
except ConnectionResetError as e:
print(e)
break
conn.close() def server1():
while True:
conn, addr = server.accept()
spawn(talk,conn) if __name__ == '__main__':
g1 = spawn(server1)
g1.join()

客户端  实现400个线程,模拟400个用户

import socket
from threading import Thread,current_thread def client():
client = socket.socket()
client.connect(('127.0.0.1',8080))
n = 0
while True: data = '%s %s'%(current_thread().name,n)
client.send(data.encode('utf-8'))
res = client.recv(1024)
print(res.decode('utf-8'))
n += 1 for i in range(400):
t = Thread(target=client)
t.start()

进程池和线程池、协程、TCP单线程实现并发的更多相关文章

  1. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  2. Python并发编程之进程池与线程池

    一.进程池与线程池 python标准模块concurrent.futures(并发未来) 1.concurrent.futures模块是用来创建并行的任务,提供了更高级别的接口,为了异步执行调用 2. ...

  3. 进程池与线程池、协程、协程实现TCP服务端并发、IO模型

    进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...

  4. Event事件、进程池与线程池、协程

    目录 Event事件 进程池与线程池 多线程爬取梨视频 协程 协程目的 gevent TCP服务端socket套接字实现协程 Event事件 用来控制线程的执行 出现e.wait(),就会把这个线程设 ...

  5. 进程池与线程池基本使用、协程理论与实操、IO模型、前端、BS架构、HTTP协议与HTML前戏

    昨日内容回顾 GIL全局解释器锁 1.在python解释器中 才有GIL的存在(只与解释器有关) 2.GIL本质上其实也是一把互斥锁(并发变串行 牺牲效率保证安全) 3.GIL的存在 是由于Cpyth ...

  6. 05网络并发 ( GIL+进程池与线程池+协程+IO模型 )

    目录 05 网络并发 05 网络并发

  7. python系列之 - 并发编程(进程池,线程池,协程)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  8. python并发编程之进程池,线程池,协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  9. Python 37 进程池与线程池 、 协程

    一:进程池与线程池 提交任务的两种方式: 1.同步调用:提交完一个任务之后,就在原地等待,等任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行 2.异步调用:提交完一个任务之后, ...

随机推荐

  1. imm自动发现有问题,监控项不再支持

    IPMI是计算机系统的远程"关闭"或"带外"管理的标准接口.它可以独立于操作系统直接从所谓的"带外"管理卡监视硬件状态.华为的服务器叫做BM ...

  2. 如何优化SpringBoot的项目的启动速度

    日常开发SpringBoot项目启动类都用@SpringBootApplication,实际上它是下面三个注解的组合: @EnableAutoConfiguration: enable Spring ...

  3. Macbook Pro 键盘触摸板失灵,只有电源键有反应 修复手札

    上次说到换完电池后键盘和触摸板就没反应了,只好硬着头皮把所有的元件一个个拆下来试. 经过3天的测试(试了网上所有能找到的办法,最多的就是重置smc和nvmp),最终确定故障应该在触摸板排线上. 没有废 ...

  4. R = [obj for obj in recs[imagename] if obj['name'] == classname] KeyError: '007765'

    在用RFBNet做测试的时候,好几次总是遇到 R = [obj for obj in recs[imagename] if obj['name'] == classname]  KeyError: ' ...

  5. UDF——判断边界类型

  6. Python-DDT框架

    Install pip install ddt 实例 import unittest from ddt import ddt, data, unpack @ddt class MyTestCase(u ...

  7. 工具系列 | PHPSTROM 连接Docker容器 && 配置XDEBUG调试

    Docker 客户端配置 PHPSTROM 配置 选择连接 容器日志 配置Xdebug 开启Debug模式 打断点 浏览器访问该项目地址:http://wiot.frp.tinywan.top/

  8. C++11原子操作与无锁编程(转)

    不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...

  9. java性能优化之HashMap,LinkedHashMap,TreeMap读取大量数据效率的比较

    很多时候,我们用jdbctemplate或mybatis的时候,为了查询通用,会选择使用map数据结构,因为hashmap本身无序,所以为了保证key的有序性,会采用linkedhashmap.所以我 ...

  10. java 从 PKCS12(比如pfx格式)证书中提取私钥证书(PrivateKey)和受信任的公钥证书(X509Certificate)的序列号(SerialNumber)

    import lombok.Cleanup; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; impor ...