1.协程
并发:切+保存状态
单线程下实现并发:协程 切+ 保存状态 yield
遇到io切,提高效率
遇到计算切,并没有提高效率 检测单线程下 IO行为 io阻塞 切
相当于骗操作系统 一直处于计算
协程:。。。
单线程下实现并发:根本目标:遇到IO就切,一个线程的整体IO降下来
程序用的cpu 时间长,就叫执行效率高
效率最高:多个进程 (多个cpu)
每个进程开多个线程
每个线程用到协程 (IO就切)
总结协程特点:
 #并发执行
import time def producer():
g=consumer()
next(g)
for i in range(10000000): # 计算
g.send(i) def consumer():
while True:
res=yield start_time=time.time()
producer()
stop_time=time.time()
print(stop_time-start_time) #串行
import time def producer():
res=[]
for i in range(10000000):
res.append(i)
return res def consumer(res):
pass start_time=time.time()
res=producer()
consumer(res)
stop_time=time.time()
print(stop_time-start_time)
2.greenlet模块
pip3 install greenlet
greenlet:可以很方便的切 但不能检测到 遇到IO 切
greenlet 比yield 好 但是还是不好 遇到io不会切
 from greenlet import greenlet
import time def eat(name):
print('%s eat 1' %name)
time.sleep(10) # 遇到io 不会立即切
g2.switch('egon')
print('%s eat 2' %name)
g2.switch() def play(name):
print('%s play 1' %name )
g1.switch()
print('%s play 2' %name ) g1=greenlet(eat)
g2=greenlet(play) g1.switch('egon') # 第一次切 需要传参数
3.gevent模块
pip3 install gevent
gevent:封装了greenlet模块,但是他能检测到io 自动切
只能检测到gevent.sleep() gevent的IO阻塞
加上补丁后,就可以检测到所有的IO 原理是:将阻塞变为非阻塞
from gevent import monkey;monkey.patch_all()
这种形式的协程 才能帮我们提升效率 从始至终 就一个线程
gevent.joinall([g1,g2]) 等待全部执行完 gevent 模块:监测单线程下多个任务得IO行为实现遇到IO就自动切到另一个任务去执行
提升单线程运行效率
应用场景:单线程下多个任务io密集型
ftp io密集型 线程来回切 比os q切 小路高
 from gevent import monkey;monkey.patch_all()  # 一定要放在程序的开头 检测所以的io 将阻塞变成非阻塞
import gevent
import time def eat(name):
print('%s eat 1' % name)
time.sleep(3) # 7s多一些 gevent 只识别 gevent 的 io操作
# gevent.sleep(3) # 4s 多一些
print('%s eat 2' % name) def play(name):
print('%s play 1' % name)
time.sleep(4)
# gevent.sleep(4)
print('%s play 2' % name) start_time=time.time()
g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex') g1.join()
g2.join()
stop_time=time.time()
print(stop_time-start_time)
"""
egon eat 1
alex play 1
egon eat 2
alex play 2
4.001747369766235 """
"""
egon eat 1
egon eat 2
alex play 1
alex play 2
7.0017828941345215
"""
"""
egon eat 1
alex play 1
egon eat 2
alex play 2
4.001675367355347
""" from gevent import monkey;monkey.patch_all()
import gevent
import time def eat(name):
print('%s eat 1' % name)
time.sleep(3)
print('%s eat 2' % name) def play(name):
print('%s play 1' % name)
time.sleep(4)
print('%s play 2' % name) g1=gevent.spawn(eat,'egon') # 异步操作
g2=gevent.spawn(play,'alex') # time.sleep(5) # 得等到 全部执行完 # g1.join() # 等到 全部执行完
# g2.join() gevent.joinall([g1,g2]) # 等到g1 g2 全部执行完
"""
egon eat 1
alex play 1
egon eat 2
alex play 2
"""
4.gevent实现并发的套接字通信
# 500 客户端同时 登录 服务端:这里1个线程 抗住了 500个client
# 这里也说明了:单线程下面io问题降下来,效率大幅度提高 说明
使用:多进程
多线程
一个线程io 问题解决了 效率大大得提高
服务端:
 #基于gevent实现
from gevent import monkey,spawn;monkey.patch_all()
from socket import * def communicate(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break conn.close() def server(ip,port):
server = socket(AF_INET, SOCK_STREAM)
server.bind((ip,port))
server.listen(5) while True:
conn, addr = server.accept()
spawn(communicate,conn) # 这里没必要加join server.close() if __name__ == '__main__':
g=spawn(server,'127.0.0.1',8090)
g.join()
客户端:
 from socket import *
from threading import Thread,currentThread def client(): #
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8090)) while True:
client.send(('%s hello' %currentThread().getName()).encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8')) client.close() # 500 客户端同时 登录 服务端:这里1个线程 抗住了 500个client
# 这里也说明了:单线程下面io问题降下来,效率大幅度提高
if __name__ == '__main__':
for i in range(500): # 500 客户端同时 登录 服务端:这里1个线程 抗住了 500个client
t=Thread(target=client)
t.start()

并发编程 - 协程 - 1.协程概念/2.greenlet模块/3.gevent模块/4.gevent实现并发的套接字通信的更多相关文章

  1. python 并发编程 基于gevent模块 协程池 实现并发的套接字通信

    基于协程池 实现并发的套接字通信 客户端: from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(('12 ...

  2. Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象

    一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...

  3. 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令

    1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...

  4. Python 37 基于多线程实现套接字 、gevent 、单线程下实现并发的套接字通信

    一:基于多线程实现套接字 可添加多个客户端 from socket import * from threading import Thread def comunicate(conn): while ...

  5. python 之 网络编程(基于TCP协议的套接字通信操作)

    第八章网络编程 8.1 基于TCP协议的套接字通信 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连 ...

  6. python 并发编程 多线程 多线程实现并发的套接字通信

    进程内会生成一个主线程,让主线程执行server函数,server函数核心是accept(),让主线程干accept的工作, 建立连接,每建立一个连接应该执行通信函数 每建立一个连接就是生成一个子线程 ...

  7. python 并发编程 基于gevent模块实现并发的套接字通信

    之前线程池是通过操作系统切换线程,现在是程序自己控制,比操作系统切换效率要高 服务端 from gevent import monkey;monkey.patch_all() import geven ...

  8. python 并发编程 基于线程池实现并发的套接字通信

    不应该让服务端随着 并发的客户端数量增多,而无数起线程,应该用线程池,限制线程数量,控制最大并发数 io密集型程序,最大并发数是2 客户端 from socket import * client = ...

  9. (网络编程)基于tcp(粘包问题) udp协议的套接字通信

    import   socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...

随机推荐

  1. linux下挂载win7的共享文件夹

    由于跨平台开发的需要,需要在Linux和windows之间共享文件夹,所以找了一下方法,我试验了两种都可以使用. 首先声明一下我使用的是VMware10.CentOS6.2 一.手动操作 1.按照下图 ...

  2. 文件操作之格式化IO

    其实在我使用最多的文件操作中,还是喜欢格式化IO控制的方式,简单方便易理解. #include <stdio.h> #include<stdlib.h> int main() ...

  3. spark mysql读写

    val data2Mysql2 = (iterator: Iterator[(String, Int)]) => { var conn: Connection = null; var ps: P ...

  4. golang Time to String

    golang Time to String allenhaozi · 2016-09-02 09:00:00 · 2447 次点击 · 预计阅读时间 1 分钟 · 19分钟之前 开始浏览 这是一个创建 ...

  5. thinkphp 如何调用百度echarts 数据报表插件

    echarts官网网址:http://echarts.baidu.com/ echarts源码地址:http://echarts.baidu.com/build/echarts-2.2.7.zip   ...

  6. High-level NavMesh Building Components

    Here we introduce four high level components for the navigation system: //这里我们介绍四个高水平导航系统组件: NavMesh ...

  7. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  8. mysql -- 按时间查询 今天、昨天、明天、上月....

    今天   select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天   SELECT * FROM 表名 WHERE TO_DAYS( NO ...

  9. &lt;LeetCode OJ&gt; 217./219. Contains Duplicate (I / II)

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

  10. hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)

    还是畅通工程 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...