在操作系统中进程是资源分配的最小单位, 线程是CPU调度的最小单位。

协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。也就是说程序员用代码来控制切换.

参考: http://www.cnblogs.com/Eva-J/articles/8324673.html

# 进程 启动多个进程 进程之间是由操作系统负责调用
# 线程 启动多个线程 真正被CPU执行的最小单位实际是线程
# 开启一个线程 创建一个线程 寄存器 堆栈
# 关闭一个线程 # 协程
# 本质上是一个线程
# 能够在多个任务之间切换来节省一些IO时间
# 协程中任务之间的切换也消耗时间,但是开销要远远小于进程线程之间的切换
# 实现并发的手段 import time
def consumer():
while True:
x = yield
time.sleep(1)
print('处理数据 :',x) def producer():
c = consumer()
next(c)
for i in range(10):
time.sleep(1)
print('生产数据:',i)
c.send(i) # 这个生产者消费者模型 模拟了程序的来回切换, 但是不能规避IO时间
producer()

使用pip3 install greenlet 和 pip3 install gevent 安装好模块,继续:

# 真正的协程模块就是使用greenlet完成的切换
from greenlet import greenlet def eat():
print('eating start')
g2.switch() # 切换到g2
print('eating end')
g2.switch() def play():
print('playing start')
g1.switch() # 切换到g1
print('playing end') g1 = greenlet(eat) # 委托给g1
g2 = greenlet(play)
g1.switch()
  • greenlet可以实现协程,不过每一次都要人为的去指向下一个该执行的协程,显得太过麻烦。python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent

参考:https://www.cnblogs.com/PrettyTom/p/6628569.html

# 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
import time
import gevent def eat():
print('eating start')
# time.sleep(1) # gevent 不能感知到time.sleep时间
gevent.sleep(1)
print('eating end') def play():
print('playing start')
gevent.sleep(1)
print('playing end') g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()
g2.join()

gevent的正确方式:

## 导入这句,将所有模块中的阻塞IO都打成一个包。就可以感知 time.sleep
from gevent import monkey;monkey.patch_all()
import time
import gevent
import threading def eat():
print(threading.current_thread().getName()) # Dummy 假的,虚拟的。
print(threading.current_thread())
print('eating start')
time.sleep(1.2)
print('eating end') def play():
print(threading.current_thread().getName())
print(threading.current_thread())
print('playing start')
time.sleep(1)
print('playing end') g1 = gevent.spawn(eat) # 注册到协程,遇到IO将自动切换
g2 = gevent.spawn(play)
# g1.join()
# g2.join()
gevent.joinall([g1,g2])
print('master')
# 进程和线程的任务切换由操作系统完成
# 协程任务之间的切换由程序(代码)完成,只有遇到协程模块能识别的IO操作的时候,程序才会进行任务切换,实现并发的效果

同步和异步:

# 同步 和 异步
from gevent import monkey;monkey.patch_all()
import time
import gevent def task(n):
time.sleep(1)
print(n) def sync():
for i in range(5):
task(i) def async():
g_lst = []
for i in range(5):
g = gevent.spawn(task,i)
g_lst.append(g)
gevent.joinall(g_lst) # for g in g_lst:g.join() sync() # 同步
async() # 异步

爬虫时使用协程并发

# 协程 : 能够在一个线程中实现并发效果的概念
# 能够规避一些任务中的IO操作
# 在任务的执行过程中,检测到IO就切换到其他任务 # 多线程 被弱化了
# 协程 在一个线程上 提高CPU 的利用率
# 协程相比于多线程的优势 切换的效率更快 # 爬虫的例子
# 请求过程中的IO等待
from gevent import monkey;monkey.patch_all()
import gevent
from urllib.request import urlopen # 内置的模块 def get_url(url):
response = urlopen(url)
content = response.read().decode('utf-8')
return len(content) g1 = gevent.spawn(get_url,'http://www.baidu.com')
g2 = gevent.spawn(get_url,'http://www.sogou.com')
g3 = gevent.spawn(get_url,'http://www.taobao.com')
g4 = gevent.spawn(get_url,'http://www.hao123.com')
g5 = gevent.spawn(get_url,'http://www.cnblogs.com')
gevent.joinall([g1,g2,g3,g4,g5])
print(g1.value)
print(g2.value)
print(g3.value)
print(g4.value)
print(g5.value) ret = get_url('http://www.baidu.com')
print(ret)

python并发_协程的更多相关文章

  1. python 并发编程 协程 目录

    python 并发编程 协程 协程介绍 python 并发编程 协程 greenlet模块 python 并发编程 协程 gevent模块 python 并发编程 基于gevent模块实现并发的套接字 ...

  2. python并发编程&协程

    0x01 前导 如何基于单线程来实现并发? 即只用一个主线程(可利用的cpu只有一个)情况下实现并发: 并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操 ...

  3. python 并发编程 协程 gevent模块

    一 gevent模块 gevent应用场景: 单线程下,多个任务,io密集型程序 安装 pip3 install gevent Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步 ...

  4. Python之路【第十七篇】:Python并发编程|协程

    一.协程 协程,又叫微线程,纤程.英文名Coroutine.协程本质上就是一个线程 优点1:协程极高的执行效率.因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线 ...

  5. Python并发编程协程(Coroutine)之Gevent

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...

  6. python 并发编程 协程 协程介绍

    协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的 需要强调的是: 1. python的线程属于内 ...

  7. Python并发编程-协程

    利用Greenlet模块在多线程之间切换 from greenlet import greenlet def eat(): print('eating start') g2.switch() prin ...

  8. python 并发编程 协程池

    协程池 from gevent.pool import Pool from gevent import monkey;monkey.patch_all() import gevent from gev ...

  9. Python并发编程-协程实现socketserver

    #server.py from gevent import monkey;monkey.patch_all() import socket import gevent sk = socket.sock ...

随机推荐

  1. curl提交请求时,如何把cookie带过去

    curl请求有一个CURLOPT_COOKIE参数,把获取到的cookie内容,通过字符串组装,赋值给这个参数就可以了 例子:   $defaults = array( CURLOPT_URL =&g ...

  2. qtpy.PythonQtError: No Qt bindings could be found

     vnpy框架下No Qt bindings could be found  在 pycharm 里面出现  qtpy.PythonQtError: No Qt bindings could be f ...

  3. react state成员

    组件中包括state,props与render成员函数. react中,主要通过定义state,根据不同state渲染对应用户界面. 过程调用了成员函数setState(data,callback). ...

  4. [Ubuntu] 运行.AppImage格式文件

    右键Properties, Permissions勾选Allow executing file as program,如图

  5. go安装和开发工具安装

    go适合做什么 l 服务端开发 l 分布式系统 l 网络编程 l 区块链开发 l 内存KV数据库,例如boltDB.levelDB l 云平台 一 go安装 官网:https://golang.goo ...

  6. 『高性能模型』卷积复杂度以及Inception系列

    转载自知乎:卷积神经网络的复杂度分析 之前的Inception学习博客: 『TensorFlow』读书笔记_Inception_V3_上 『TensorFlow』读书笔记_Inception_V3_下 ...

  7. Django-CSRF的使用

    1. 为什么要有csrf_token? 防止跨站请求伪造 2. Django中如何使用? urls.py: urlpatterns = [ # 测试跨站请求伪造 (CSRF) url(r'^csrf_ ...

  8. Django_创建项目

    安装django pip install Django 将下面路径添加到系统环境变量的path中 C:\Users\12978\AppData\Local\Programs\Python\Python ...

  9. ES5原型琏继承

    function add(){}; add.prototype.showName = "MAN";add.prototype.name = function(){ console. ...

  10. java字符串根据正则表达式让单词首字母大写

    public class Da { public static void main(String[] args) { String s = "hello_*java_*world" ...