进程池线程池 协程 gvent 单线程实现并发套接字
1.基于多线程实现套接字服务端支持并发
服务端
from socket import * from threading import Thread def comunicate(conn): while True: # 通信循环 try: data = conn.recv(1024) if len(data) == 0: break conn.send(data.upper()) except ConnectionResetError: break conn.close() def server(ip, port, backlog=5): server = socket(AF_INET, SOCK_STREAM) server.bind((ip, port)) server.listen(backlog) while True: # 链接循环 conn, client_addr = server.accept() print(client_addr) # 通信 t=Thread(target=comunicate,args=(conn,)) t.start() if __name__ == '__main__': s=Thread(target=server,args=('127.0.0.1',8081)) s.start()
客户端
from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8081)) while True: msg=input('>>: ').strip() if len(msg) == 0:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8'))
2.进程池
使用进程池就是对启动进程数加以限制
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import time,random,os def task(name,n): print('%s%s is running'%(name,os.getpid())) time.sleep(random.randint(1,3)) return n if __name__ == '__main__': # print(os.cpu_count())#打印cpu核数 p=ProcessPoolExecutor(4)#进程池预留了4个进程,可以提供开启。后续一次性可以同时开启4个进程,进程号不会变。 # 如果不传参数(数字),那么默认最多开启的进程数为电脑的核数 l=[] for i in range(20): #同步提交 # res=p.submit(task,'进程pid:').result() # print(res) #异步提交 future=p.submit(task,'进程pid:',i)#submit是异步提交,直接传位置参数,或关键字参数 l.append(future) p.shutdown(wait=True)#关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕 for future in l: print(future.result()) print('主')
不使用回调函数进行异步提交,自行解析
import time, os, random from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor from threading import Thread import requests def get(url): print('%s GET %s' % (os.getpid(), url)) time.sleep(random.randint(1, 3)) response = requests.get(url) if response.status_code == 200: return response.text else: return '下载失败' def parse(res): 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.bilibili.com', 'https://www.youku.com', 'https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com', ] p = ProcessPoolExecutor(4) l = [] for url in urls: future = p.submit(get, url) l.append(future) p.shutdown(wait=True) for future in l: res = future.result() parse(res) print('主')
异步一般与回调函数连用
使用回调函数
import time, os, random from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor from threading import Thread import requests def get(url): print('%s GET %s' % (os.getpid(), url)) time.sleep(random.randint(1, 3)) response = requests.get(url) if response.status_code == 200: return response.text else: return '下载失败' def parse(res): res=res.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.bilibili.com', 'https://www.youku.com', 'https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com', ] p = ProcessPoolExecutor(4) 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('主%s'%os.getpid())
使用线程池开多线程进行任务
线程池和进程池的用法很相似
import time, os, random from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor from threading import Thread,current_thread import requests def get(url): print('%s GET %s' % (current_thread().name, url)) time.sleep(random.randint(1, 3)) response = requests.get(url) if response.status_code == 200: return response.text else: return '下载失败' def parse(res): res=res.result() print('%s解析结果为%s' % (current_thread().name, 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.bilibili.com', 'https://www.youku.com', 'https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com', ] p = ThreadPoolExecutor(4) start=time.time() for url in urls: future = p.submit(get, url) future.add_done_callback(parse)#parse会在任务完毕后触发,然后接收一个参数future对象 #如果开启的是进程,那么来干parse这件事的是主进程 #如果开启的是线程,那么线程池里的线程也可以来做parse,谁有空谁做 p.shutdown(wait=True) print(time.time()-start) print('主%s'%current_thread().name)
3.协程
使用协程的目标是想要在单线程下实现并发
实现协程的原理是:切换+保存状态
注意:协程是程序员意淫出来的东西,操作系统里只有进程和线程的概念。
在单线程下实现多个任务间遇到IO就切换可以降低单线程的IO时间,从而最大限度地提升单线程的效率。
不遇到IO就进行切换的话并不能提升单线程的效率,这样不算是成功的协程。
4.gevent
要实现单线程下的协程,需要gevent模块
from gevent import spawn,sleep from gevent import monkey,joinall monkey.patch_all()#这样gevent就能识别所有IO行为 import time #gevent不能识别本身以外的IO行为,为了监听所有的IO行为,要导入monkey def play(name): print('%s play1'%name) time.sleep(3) print('%s play2'%name) def eat(name): print('%s eat1'%name) time.sleep(5) print('%s eat2'%name) start=time.time() g1=spawn(play,'刘清正')#这里是异步提交 g2=spawn(eat,'刘清正') joinall([g1,g2]) stop=time.time() print(stop-start)
5.单线程实现并发套接字
进程池线程池 协程 gvent 单线程实现并发套接字的更多相关文章
- python 进程、线程与协程的区别
进程.线程与协程区别总结 - 1.进程是计算器最小资源分配单位 - 2.线程是CPU调度的最小单位 - 3.进程切换需要的资源很最大,效率很低 - 4.线程切换需要的资源一般,效率一般(当然了在不考虑 ...
- 三、进程和线程、协程在python中的使用
三.进程和线程.协程在python中的使用 1.多进程一般使用multiprocessing库,来利用多核CPU,主要是用在CPU密集型的程序上,当然生产者消费者这种也可以使用.多进程的优势就是一个子 ...
- 图解Python 【第八篇】:网络编程-进程、线程和协程
本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...
- python基础之进程、线程、协程篇
一.多任务(多线程) 多线程特点:(1)线程的并发是利用cpu上下文的切换(是并发,不是并行)(2)多线程执行的顺序是无序的(3)多线程共享全局变量(4)线程是继承在进程里的,没有进程就没有线程(5) ...
- python并发编程之进程、线程、协程的调度原理(六)
进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...
- Python3 进程、线程和协程
Infi-chu: http://www.cnblogs.com/Infi-chu/ 进程.线程和协程的对比 1.定义对比 进程:是系统进行资源分配的基本单位,每启动一个进程,操作系统都需要为其分配运 ...
- 协程、gevent实现异步io、进程、线程、协程对比
异步io的说白了就是遇到io操作的时候,就停下来去做别的事情.io分网络io和磁盘io,网络io比如说打开一个网站获取数据,下载一首歌等等,磁盘io就是把数据存到一个文件里面,写到磁盘上. 从网站上获 ...
- Python进程、线程、协程及IO多路复用
详情戳击下方链接 Python之进程.线程.协程 python之IO多路复用
- 进程、线程、协程和GIL(二)
上一篇博客讲了进程.线程.协程和GIL的基本概念,这篇我们来说说在以下三点: 1> python中使用threading库来创建线程的两种方式 2> 使用Event对消来判断线程是否已启动 ...
随机推荐
- Android进阶:ListView性能优化异步加载图片 使滑动效果流畅
ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很 ...
- Docker详解
一.Docker 简介 Docker 两个主要部件: Docker: 开源的容器虚拟化平台 Docker Hub: 用于分享.管理 Docker 容器的 Docker SaaS 平台 -- Docke ...
- 10.14 预订会议室的小Demo
2018-10-14 17:12:32 越努力,越幸运.永远不要高估自己! 网上修改一下博客网站样式,做个仿qq空间的! 放上github连接 :https://github.com/TrueNewB ...
- MacTex TexStudio Configuration 配置
在Mac上使用Latex的话主流是安装MacTex,对于IDE的选择有很多,像什么自带的TexShop,或者是TexStudio,Latexian,Texpad,Texmaker等,甚至可以直接使用一 ...
- vbox 的 ova 提取vmdk 与 vdi 以及扩容
原文: http://blog.csdn.net/flm2003/article/details/11980863 1. 从ova提取vmdk: tar xvf oldImage.ova => ...
- 180714、JRebel插件安装配置与破解激活(多方案)详细教程
JRebel 介绍 IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,浪费不少生命啊.目前对于idea热部署最好的解决方案就是安装JRebel插件 ...
- angular 上传图像的使用总结
AngularJS 的文件上传控件有两个:(1) angular-file-upload:https://github.com/nervgh/angular-file-upload(2) ng-fil ...
- cordova 内部API 用ssl https,报错
环境:node6.10.1 cordova 6.x, ionic 2.2.1 用cordova/ionic 建立的app我们的api 地址要用https,做了安全加密之后,按照正常的流程,打包,然后跑 ...
- ssh agent-forward
出于安全性考虑,服务器迁移后,将统一使用 SSH agent forwarding 方式登录所有服务器, 原则上所有 ssh 操作都要通过跳板机,而且跳板机上禁止存储一切私钥. 在此说明一下后续ssh ...
- go,gcvis,golang, privoxy,and git proxy
/etc/init.d/privoxy restartexport http_proxy=http://127.0.0.1:8118export https_proxy=http://127.0.0. ...