一、进程池和线程池

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

注意点:在使用进程池、线程池,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. space-cloud 支持多数据库多rest&& graphql web server

    space-cloud 是一个开源的类似hasura 的graphql 引擎,但是space-cloud 同时支持rest api,而且支持多数据库 基于golang 编写,功能看着很强大 参考图 功 ...

  2. vue-element-admin

    https://github.com/deadzq/vue-element-admin-1.git vue-element-admin使用. cnpm install npm run dev

  3. x64汇编第四讲,c / C++中调用x64汇编

    目录 x64汇编第四讲,c / C++中调用x64汇编 一丶简介 1.说明 二丶C/C++调用 asm64.asm函数. 1.配置asm参与生成 2.给Asm文件添加函数代码 3.C/C++调用asm ...

  4. PowerDesigner应用02 逆向工程之导出PDM文件前过滤元数据(表、视图、存储过程等)

    在上一篇文章<PowerDesigner应用01 逆向工程之配置数据源并导出PDM文件>步骤二中导出了目标数据库对应的PDM文件, 该文件中展示出了所有表的信息与关系. 某些业务场景下只需 ...

  5. 深入kubernetes调度之NodeSelector

    Kubernetes的调度有简单,有复杂,指定NodeName和使用NodeSelector调度是最简单的,可以将Pod调度到期望的节点上. 1 NodeNamePod.spec.nodeName用于 ...

  6. 【Beta】Scrum meeting 10

    目录 写在前面 进度情况 任务进度表 Beta-1阶段燃尽图 遇到的困难 照片 commit记录截图 后端代码 前端代码 技术博客 写在前面 例会时间:5.14 22:30-22:45 例会地点:微信 ...

  7. 【Beta】Phylab 测试报告

    PhyLab Beta 测试报告 测试中发现的bug Beta阶段新Bug Bug 可能原因 markdown生成的报告可能溢出显示框 表格过长,显示框未设置横向溢出 移动端实验区无法评论 移动端社区 ...

  8. JetBrains套装免费学生授权申请(IntelliJ, ReSharper, WebStorm...)

    IntelliJ作为一款强大的Java开发IDE,售价自然也不会低.但是对于学生或教师来说,JetBrains开发工具免费提供给学生和教师使用.而且取得一次授权后只需要使用相同的 JetBrains ...

  9. NIO网络访问模式实践

    1.创建NioNest12类 一个线程监听5个端口的事件 public class NioTest12 { public static void main(String[] args) throws ...

  10. linux 压缩、解压、zip/unzip/jar

    网上很多人说用jar命令解压,但jar命令解压时不能指定目录,推荐使用unzip解压war包. unzip -d 指定目录 [root@oracle upload]# unzip -oq common ...