<35>python学习笔记——协程

协程是一种用户态的轻量级线程

协程拥有自己的寄存器上下文和栈,能保留上一次调用时的状态。每次过程冲入时,进入上一次离开时所处逻辑流的位置。

协程是串行工作,同一时间只能执行一个携程,不需要加锁。但是进行阻塞(Blocking)操作(如IO操作时)会阻塞掉整个程序。

通过协程在单线程里实现并发效果。

适合做高并发处理。

yield关键字

send()

解决协程阻塞:

greenlet 模块

gevent 模块(基于greenlet模块)

gevent.spawn()启动一个协程

范例:单线程下并发执行一个函数

from urllib.request import urlopen
import gevent

def f(url):
    print('GET: %s' %url)
    resp = urlopen(url)
    data = resp.read()
    print('%d byte received form %s.'%(len(data),url))

#单线程下并发的执行一个下载任务
gevent.joinall([    #开启了三个协程
    gevent.spawn(f,'https://www.python.org/'),
    gevent.spawn(f,'https://www.yahoo.com'),
    gevent.spawn(f,'https://github.com/'),
])

结果:

GET: https://www.python.org/
47410 byte received form https://www.python.org/.
GET: https://www.yahoo.com
465372 byte received form https://www.yahoo.com.
GET: https://github.com/
92691 byte received form https://github.com/.

范例:单线程下的多socket并发

server side

import gevent

from gevent import socket,monkey
monkey.patch_all() #monkey 将python中的很多变成非阻塞的形式

def server(port):
    s = socket.socket()
    s.bind(('0.0.0.0',port))
    s.listen(500)
    while True:
        cli,addr = s.accept()
        gevent.spawn(handle_request,cli) #启动了一个协程,将cli客户端穿了进来

def handle_request(s):
    try:
        while True:
            data = s.recv(1024)
            print('recv:',data)
            s.send(data)
            if not data: #没有数据就断开了
                s.shutdown(socket.SHUT_WR) #把客户端销毁
    except Exception as ex:
        print(ex)
    finally:
        s.close() #把跟这个客户端的链接关掉

if __name__ =='__main__':
    server(8001) #启动在8001端口
client side

import socket

HOST = 'localhost'
PORT = 8001
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
    msg = bytes(input('>>:'),encoding='utf8')
    s.sendall(msg)
    data = s.recv(1024)

    print('Reveived',repr(data))

s.close()






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值