一、进程池与线程池

基本使用:

  进程池和线程池操作一样

提交任务的两种方式:

同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的

异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的

同步调用

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模块相关推荐

  1. python gevent async_详解python之协程gevent模块

    进程.线程.协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译为协同的例程,一般我们都简称为协程. 在linux系统中,线程就是轻量级的进程,而我们 ...

  2. python---基础知识回顾(十)进程和线程(协程gevent:线程在I/O请求上的优化)...

    优点:使用gevent协程,可以更好的利用线程资源.(基于线程实现) 需求:使用一个线程,去请求多个网站的资源(注意,请求上会有延时)<实际上是去请求了大量的网站信息,我们使用了多线程,只不过每 ...

  3. python协程处理海量文件_python_实战篇_使用协程gevent模块实现多任务copyA文件夹到B文件夹...

    大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油! 接着上次的通过多进程来实现多任务处理,本次使用gevent来实现协程的多任务处理 闲话不 ...

  4. Python入门学习笔记13(线程锁与信号量)

    锁的作用是在多个线程访问同一个资源时对资源进行保护,防止多线程操作造成结果不解预测 1.互斥锁 import threadingnum = 0mutex = threading.Lock();def ...

  5. python并发编程--进程、线程、协程、锁、池、队列

    文章目录 操作系统的概念 进程 multiprocessing模块 守护进程 使用多进程实现一个并发的socket的server 锁 生产者消费者模型 数据共享 线程threading模块 守护线程和 ...

  6. Python并发之协程gevent基础

    基本示例 from gevent import monkey monkey.patch_all() # 记住一定放在第一行,这里是打补丁的意思,time模块在使用协程gevent模块的时候,必须打补丁 ...

  7. python进程池和线程池_Python中的进程池与线程池(包含代码)

    引入进程池与线程池 使用ProcessPoolExecutor进程池,使用ThreadPoolExecutor 使用shutdown 使用submit同步调用 使用submit异步调用 异步+回调函数 ...

  8. python进程池和线程池_python自带的进程池及线程池

    进程池 """ python自带的进程池 """ from multiprocessing import Pool from time im ...

  9. python线程池模块_python并发编程之进程池,线程池,协程

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

  10. python是如何实现进程池和线程池的_进程、线程、线程池和协程如何理解?

    1.进程.线程.线程池的概念 进程是一个动态的过程,是一个活动的实体.简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者.可以说,进程中包含了多个可以同时运行的线程 ...

最新文章

  1. 3 月,跳还是不跳?
  2. 8个方法解决90%的NLP问题
  3. linux c 图像处理,基于uClinux的图像处理及Socket传输的实现-计算机应用与软件.PDF...
  4. 如果有一天,我们再见面
  5. Linux里的稀疏文件
  6. java面试题十六 StringBuffer
  7. 如何处理错误信息 Pricing procedure could not be determined
  8. Linux 查询股价工具,find 查找工具
  9. Framebuffer基础知识(三十)
  10. 数据挖掘前景及工作方向选择
  11. Revit二次开发之TaskDialog
  12. 我自己对英语学习的心得与体会
  13. JAVA大数据需要学什么
  14. Post方式与参数详解
  15. 斯坦福大学深度学习公开课cs231n学习笔记(10)卷积神经网络
  16. 爱情降临的时刻你在等待着
  17. matlab读txt文件
  18. Java多线程模拟实现LOL中薇恩、死歌、剑圣的操作
  19. 大专生出身?听说你在找SpringBoot整合案例?万字长文!
  20. 计算机专业考编制怎么考,大学这5类专业更适合考编制,有你的专业吗?

热门文章

  1. 计算机网络网络层实例例题
  2. 八、K8s 密码管理
  3. HCL V2.1.1如何修改CLI字体大小及背景颜色
  4. 最常用的四种设计模式
  5. map和unordered_map
  6. [转万一] 不使用标题栏拖动窗体
  7. CMOS checksum error-Defaults loaded 故障解决办法
  8. 运用.NET Framework中的类来创建看上去很专业的报表。
  9. request用法_urllib的基本用法
  10. 字长为16位的计算机_字长为16位表示这台计算机最大能计算