DAY37-Python入门学习-进程池与线程池、协程、gevent模块
一、进程池与线程池
基本使用:
进程池和线程池操作一样
提交任务的两种方式:
同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的
异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的
同步调用
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time,random,osdef task():print('%s is running'%os.getpid())i=random.randint(1,3)time.sleep(i)return iif __name__ == '__main__':p=ProcessPoolExecutor(4)l=[]for i in range(10):res = p.submit(task).result()#等待任务执行完毕,返回结果print(res)print('主')
View Code
异步调用
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time,random,osdef task():print('%s is running'%os.getpid())i=random.randint(1,3)time.sleep(i)return iif __name__ == '__main__':p=ProcessPoolExecutor(4)l=[]for i in range(10):future=p.submit(task)#只替提交任务 l.append(future)p.shutdown(wait=True)#关闭进程池入口,并在原地等待所有进程任务执行完毕for i in l:print(i.result())print('主')
View Code
异步 + 回调函数
from concurrent.futures import ProcessPoolExecutor import time,os import requestsdef get(url):print('%s GET %s' %(os.getpid(),url))time.sleep(3)response=requests.get(url)if response.status_code == 200:res=response.textelse:res='下载失败'return resdef parse(future):time.sleep(1)res=future.result()print('%s 解析结果为%s' %(os.getpid(),len(res)))if __name__ == '__main__':urls=['https://www.baidu.com','https://www.sina.com.cn','https://www.tmall.com','https://www.jd.com','https://www.python.org','https://www.openstack.org','https://www.baidu.com','https://www.baidu.com','https://www.baidu.com',]p=ProcessPoolExecutor(9)start=time.time()for url in urls:future=p.submit(get,url)future.add_done_callback(parse)#parse会在任务运行完毕后自动触发,然后接收一个参数future对象,回调函数的执行是在主进程里,而线程中的回调函数是由空闲的线程来执行 p.shutdown(wait=True)print('主',time.time()-start)print('主',os.getpid())
View Code
基于线程池的套接字通讯
服务端
from concurrent.futures import ThreadPoolExecutor import socket from threading import current_thread IP='127.0.0.1' PORT=8085 ADDRESS=(IP,PORT) BUFFSIZE=1024 t = ThreadPoolExecutor(4)def communicate(conn,addr):while True:try:data=conn.recv(BUFFSIZE)if not data:print('%s客户端断开....'%addr)breakprint('>>>>%s 端口:%s 线程:%s'%(data.decode('utf-8'),addr[1],current_thread().name))conn.send(data.upper())except ConnectionResetError:breakconn.close()if __name__ == '__main__':server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(ADDRESS)server.listen(2)print(current_thread().name)while True:conn,addr=server.accept()t.submit(communicate, conn,addr)
View Code
客户端
import socket IP='127.0.0.1' PORT=8085 ADDRESS=(IP,PORT) BUFFSIZE=1024client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(ADDRESS)while True:msg=input('>>>>').strip()if len(msg)==0:continueif msg=='q':breakclient.send(msg.encode('utf-8'))data = client.recv(BUFFSIZE)print(data.decode('utf-8'))client.close()
View Code
二、协程
1. 目标:
在线程下实现并发
并发(多个任务看起来是同时执行就是并发):切换+保存状态
2. 协程:
协程是单线程实现并发
注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)
在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率
单纯的切换,反而更降低效率
#串行执行 import timedef func1():for i in range(10000000):i+1def func2():for i in range(10000000):i+1start = time.time() func1() func2() stop = time.time() print(stop - start)#基于yield并发执行 import time def func1():while True:yielddef func2():g=func1()for i in range(10000000):i+1next(g)start=time.time() func2() stop=time.time() print(stop-start)#2.7103893756866455
View Code
三、gevent模块
1.使用
from gevent import monkey;monkey.patch_all()#用来识别IO阻塞,必须放到文件头 from gevent import spawn,joinall import timedef foo1(name):print('%s play1'%name)time.sleep(2)#模拟IO操作,遇到IO切换任务print('%s play2'%name)def foo2(name):print('%s eat1'%name)time.sleep(3)#模拟IO操作,遇到IO切换任务print('%s eat2'%name)f1=spawn(foo1,'egon')#提交任务 f2=spawn(foo2,'egon')#提交任务 joinall([f1,f2])#主线程等待任务完成 print('主')#结果:#egon play1#egon eat1#egon play2#egon eat2#主
2.基于gevent的套接字通信
服务端
from gevent import monkey;monkey.patch_all() from gevent import spawn import socket from threading import current_thread IP='127.0.0.1' PORT=8086 ADDRESS=(IP,PORT) BUFFSIZE=1024def communicate(conn,addr):while True:try:data=conn.recv(BUFFSIZE)if not data:print('%s客户端断开....'%addr)breakconn.send(data.upper())except ConnectionResetError:breakdef server():server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(ADDRESS)server.listen(2)print(current_thread().name)while True:conn,addr=server.accept()spawn(communicate,conn,addr)if __name__ == '__main__':s1=spawn(server)s1.join()
View Code
多个客户端并发
import socket from threading import Thread,current_threadIP = '127.0.0.1' PORT = 8086 ADDRESS = (IP, PORT) BUFFSIZE = 1024 def client():client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)client.connect(ADDRESS)n=0while True:msg='%s say hello %s' %(current_thread().name,n)n+=1client.send(msg.encode('utf-8'))data=client.recv(BUFFSIZE)print(data.decode('utf-8'))if __name__ == '__main__':for i in range(500):t=Thread(target=client)t.start()
View Code
转载于:https://www.cnblogs.com/xvchengqi/p/9621989.html
DAY37-Python入门学习-进程池与线程池、协程、gevent模块相关推荐
- python gevent async_详解python之协程gevent模块
进程.线程.协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译为协同的例程,一般我们都简称为协程. 在linux系统中,线程就是轻量级的进程,而我们 ...
- python---基础知识回顾(十)进程和线程(协程gevent:线程在I/O请求上的优化)...
优点:使用gevent协程,可以更好的利用线程资源.(基于线程实现) 需求:使用一个线程,去请求多个网站的资源(注意,请求上会有延时)<实际上是去请求了大量的网站信息,我们使用了多线程,只不过每 ...
- python协程处理海量文件_python_实战篇_使用协程gevent模块实现多任务copyA文件夹到B文件夹...
大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油! 接着上次的通过多进程来实现多任务处理,本次使用gevent来实现协程的多任务处理 闲话不 ...
- Python入门学习笔记13(线程锁与信号量)
锁的作用是在多个线程访问同一个资源时对资源进行保护,防止多线程操作造成结果不解预测 1.互斥锁 import threadingnum = 0mutex = threading.Lock();def ...
- python并发编程--进程、线程、协程、锁、池、队列
文章目录 操作系统的概念 进程 multiprocessing模块 守护进程 使用多进程实现一个并发的socket的server 锁 生产者消费者模型 数据共享 线程threading模块 守护线程和 ...
- Python并发之协程gevent基础
基本示例 from gevent import monkey monkey.patch_all() # 记住一定放在第一行,这里是打补丁的意思,time模块在使用协程gevent模块的时候,必须打补丁 ...
- python进程池和线程池_Python中的进程池与线程池(包含代码)
引入进程池与线程池 使用ProcessPoolExecutor进程池,使用ThreadPoolExecutor 使用shutdown 使用submit同步调用 使用submit异步调用 异步+回调函数 ...
- python进程池和线程池_python自带的进程池及线程池
进程池 """ python自带的进程池 """ from multiprocessing import Pool from time im ...
- python线程池模块_python并发编程之进程池,线程池,协程
需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...
- python是如何实现进程池和线程池的_进程、线程、线程池和协程如何理解?
1.进程.线程.线程池的概念 进程是一个动态的过程,是一个活动的实体.简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者.可以说,进程中包含了多个可以同时运行的线程 ...
最新文章
- 3 月,跳还是不跳?
- 8个方法解决90%的NLP问题
- linux c 图像处理,基于uClinux的图像处理及Socket传输的实现-计算机应用与软件.PDF...
- 如果有一天,我们再见面
- Linux里的稀疏文件
- java面试题十六 StringBuffer
- 如何处理错误信息 Pricing procedure could not be determined
- Linux 查询股价工具,find 查找工具
- Framebuffer基础知识(三十)
- 数据挖掘前景及工作方向选择
- Revit二次开发之TaskDialog
- 我自己对英语学习的心得与体会
- JAVA大数据需要学什么
- Post方式与参数详解
- 斯坦福大学深度学习公开课cs231n学习笔记(10)卷积神经网络
- 爱情降临的时刻你在等待着
- matlab读txt文件
- Java多线程模拟实现LOL中薇恩、死歌、剑圣的操作
- 大专生出身?听说你在找SpringBoot整合案例?万字长文!
- 计算机专业考编制怎么考,大学这5类专业更适合考编制,有你的专业吗?