一、协程

  1、又称微线程,纤程。英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程(相当于操作系统不知道它的存在,是用户控制的)。

  2、协程拥有自己的寄存器上下文和栈(代码的必要的代码段和)。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

  3、协程一定是在单线程中运行的。

二、协程的优点与缺点

  优点:

  1、无需线程上下文切换的开销。

  2、无需原子操作(最小级别的操作)锁定及同步的开销。

  3、方便切换控制流,简化编程模型。

  4、高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题,所以很适合用于高并发处理。

  缺点:

  1、无法利用多核资源:协程的本质是个单线程,它不能同时将单个CPU的多个核用上,协程需要和进程配合才能运行在多CPU上,当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。

  2、进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序。

三、使用yield实现协程操作例子

  1、使用yield实现的一个最简单的协程的效果

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-4
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 import time
import queue def consumer(name):
print("starting eating baozi...")
while True:
new_baozi = yield
print("[%s] is eating baozi %s" %(name,new_baozi)) def producer():
r = con.__next__()
r = con2.__next__()
n = 0
while n < 5:
n += 1
con.send(n)
con2.send(n)
print("\033[32;1m[producer]\033[0m is making") if __name__ == "__main__":
con = consumer("c1")
con2 = consumer("c2") p = producer()

  执行结果:

 C:\Users\wohaoshuai\AppData\Local\Programs\Python\Python36\python.exe E:/PythonLearn/day16/pro_consume.py
starting eating baozi...
starting eating baozi...
[c1] is eating baozi 1
[c2] is eating baozi 1
[producer] is making
[c1] is eating baozi 2
[c2] is eating baozi 2
[producer] is making
[c1] is eating baozi 3
[c2] is eating baozi 3
[producer] is making
[c1] is eating baozi 4
[c2] is eating baozi 4
[producer] is making
[c1] is eating baozi 5
[c2] is eating baozi 5
[producer] is making Process finished with exit code 0

  2、greenlet

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-4
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 from greenlet import greenlet def test1():
print(12)
gr2.switch()
print(34)
gr2.switch() def test2():
print(56)
gr1.switch()
print(78) gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

执行结果:

 C:\Users\wohaoshuai\AppData\Local\Programs\Python\Python36\python.exe E:/PythonLearn/day16/pro_consume.py
12
56
34
78 Process finished with exit code 0

  3、gevent

    a、gevent是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是greenlet,它是以C扩展模块形式接入Python的轻量级协程。greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-1
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 import gevent def foo():
print("Running in foo")
gevent.sleep(1)
print("Explicit context switch to foo again") def bar():
print("Explicit context to bar")
gevent.sleep(1)
print("Implicit context switch back to bar") def ex():
print("Explicit context to ex")
gevent.sleep(1)
print("Implicit context switch back to ex") gevent.joinall([
gevent.spawn(foo), #类似产生一个协程的foo
gevent.spawn(bar), #产生一个协程的bar
gevent.spawn(ex)
]) #代码的效果为:第一个协程切换到第二个,第二个切换到第三个,然后又遇到sleep(模拟io)又切换到下一个,然后实现并发的协程的效果

    执行结果

 C:\Users\wohaoshuai\AppData\Local\Programs\Python\Python36\python.exe E:/PythonLearn/day16/pro_consume.py
Running in foo
Explicit context to bar
Explicit context to ex
Explicit context switch to foo again
Implicit context switch back to bar
Implicit context switch back to ex Process finished with exit code 0

  b、通过协程爬取网页实例

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-5
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 from gevent import monkey;monkey.patch_all()
import gevent from urllib.request import urlopen def f(url):
print("GET: %s" %url)
resp = urlopen(url)
data = resp.read()
print("%d bytes received from %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"),
])

执行结果:

 C:\Users\wohaoshuai\AppData\Local\Programs\Python\Python36\python.exe E:/PythonLearn/day16/pro_consume.py
GET: https://www.python.org/
GET: https://www.yahoo.com/
GET: https://github.com
80704 bytes received from https://github.com.
50008 bytes received from https://www.python.org/.
528149 bytes received from https://www.yahoo.com/. Process finished with exit code 0

  c、通过gevent实现单线程下的多socket并发

    server端

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-5
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 import gevent
from gevent import socket,monkey
monkey.patch_all() #python中的一种黑魔法,只要写入一句话就自动的把python中的许多标准库变为非阻塞的模式 def server(port):
s = socket.socket()
s.bind(("0.0.0.0",port))
s.listen(5000)
while True:
cli,addr = s.accept()
gevent.spawn(handle_request,cli) #执行handle_request函数,参数是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_RD) #如果接收为空值,结束
except Exception as ex:
print(ex)
finally:
s.close() if __name__ == "__main__":
server(8001)

    client端

 #!/usr/bin/python
# -*- coding : utf-8 -*-
# 作者: Presley
# 时间: 2018-12-5
# 邮箱:1209989516@qq.com
# 这是我用来练习python 协程的测试脚本 import socket HOST = "localhost"
PORT = 8001
s = socket.socket()
s.connect((HOST,PORT)) while True:
msg = input(">>:")
if not msg:continue
msg = msg.encode("utf-8")
s.sendall(msg)
data = s.recv(1024)
print("Received",data.decode("utf-8"))
s.close()

Python 携程的更多相关文章

  1. python 携程asyncio 实现高并发示例2

    https://www.bilibili.com/video/BV1g7411k7MD?from=search&seid=13649975876676293013 import asyncio ...

  2. python 携程asyncio实现高并发示例1

    import asyncio #携程(携程不是函数) async def print_hello(): while True: print("hello world") await ...

  3. Python线程,进程,携程,I/O同步,异步

    只有本人能看懂的-Python线程,进程,携程,I/O同步,异步 举个栗子: 我想get三个url,先用普通的for循环 import requests from multiprocessing im ...

  4. python爬虫-携程-eleven参数

    携程-eleven分析 一.eleven的位置 通过对旁边栈的分析,它是在另一个js文件中调用的.那个js文件是一个自调用的函数,所以我们可以直接copy下来,用浏览器执行看看 执行运行是会报错的,u ...

  5. python对比线程,进程,携程,异步,哪个快

    目录概念介绍测试环境开始测试测试[单进程单线程]测试[多进程 并行]测试[多线程 并发]测试[协程 + 异步]结果对比绘图展示概念介绍首先简单介绍几个概念: 进程和线程进程就是一个程序在一个数据集上的 ...

  6. 进程、线程和携程的通俗解释【刘新宇Python】

    通过下面这张图你就能看清楚了,进程.线程和携程的关系   进程: 多个进程是可以运行在多个CPU当中的,比如你的电脑是4核,可以同时并行运行四个进程,这是真正物理上的并行运行. 线程: 每个进程又可以 ...

  7. 我所了解的各公司使用的 Ceph 存储集群 (携程、乐视、有云、宝德云、联通等)

    Ceph 作为软件定义存储的代表之一,最近几年其发展势头很猛,也出现了不少公司在测试和生产系统中使用 Ceph 的案例,尽管与此同时许多人对它的抱怨也一直存在.本文试着整理作者了解到的一些使用案例. ...

  8. Python 协程 61

    什么是协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程的特点 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到 ...

  9. 18 11 26 用多进程 多线程 携程 实现 http 服务器的创建

    下面是一个  多进程 服务器的创建 import socket import re import multiprocessing def service_client(new_socket): &qu ...

随机推荐

  1. 使用Vagrant搭建本地python开发环境

    使用Vagrant搭建本地python开发环境 关于vagrant:Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境,它使用Oracle的开源VirtualBox虚拟化系统也可以使 ...

  2. DHTMLX Tree中文开发指导

    专业版1.6下载地址(CSDN) http://download.csdn.net/source/1388340 版本号:dhtmlxTree v.1.6 Professional edition b ...

  3. HBase在HDFS上的目录介绍

    总所周知,HBase 是天生就是架设在 HDFS 上,在这个分布式文件系统中,HBase 是怎么去构建自己的目录树的呢? 第一,介绍系统级别的目录树. 一.0.94-cdh4.2.1版本 系统级别的一 ...

  4. ES的Query、Filter、Metric、Bucketing使用详解

    由于笔者在实际项目仅仅将ES用作索引数据库,并没有深入研究过ES的搜索功能.而且鉴于笔者的搜索引擎知识有限,本文将仅仅介绍ES简单(非全文)的查询API. 笔者原本打算在本文中介绍聚合API的内容,但 ...

  5. STM32应用实例十一:基于SPI和AD7192的数据采集

    在开发臭氧发生器的时,我们需要一个高分辨率的AD采集,于是选择了AD7192,选择这款ADC的原因比较简单.首先它是24位的符合我们的精度要求:其次它自带时钟,便于节省空间:第三他又4路单端或2路差分 ...

  6. 疯狂Workflow讲义——基于Activiti的工作流应用开 PDF 下载

    <疯狂Workflow讲义--基于Activiti的工作流应用开> 一:文档获取下载方式: 1:花20CSDN积分:可以下载:http://download.csdn.net/downlo ...

  7. Java测试代码(很不完整,建议大家别看,过几天会再发一次难的版本)

    package ATM;  import java.io.BufferedReader;  import java.io.InputStreamReader;  class Account{ priv ...

  8. error: js/dist/app.js from UglifyJs Unexpected token: name (Dom7)

    What you did I have installed Swiper as normal dependency in my Project and import it to my scripts ...

  9. mac 端口占用问题

    查看端口号 终端输入:sudo lsof -i tcp:port 将port换成被占用的端口(如:8086.9998) 将会出现占用端口的进程信息. 杀死占用端口的PID进程 找到进程的PID,使用k ...

  10. Netty简单聊天室

    1.创建maven项目,在pom.xml中引入netty的jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xm ...