在操作系统中进程是资源分配的最小单位, 线程是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. oracle 存储过程(分析理解)

    我的理解 比较简单(仅供参考)   存储过程就相当于java里面的方法 简单讲就是一串代码能够实现某个特定的功能,想要使用这个方法直接调用方法名就能够使用他的功能,这就是方法 oracle 存储过程也 ...

  2. Unity --- 在原目录中,将选中的Texture剥离为rgb和alpha

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; us ...

  3. stm32WB55xx 外设资源

    1.FLASH(闪存) 2.Radio System(无线系统:兼容BLE5.0与IEEE802.15.4标准,由2.4GHz射频前端.BLE和IEEE802.15.4物理层控制器组成,无线低功耗协议 ...

  4. Day 4 变量常量

    编辑语言的分类 编程语言,他是人与计算机沟通的一种介质 机器语言 计算机只认识0和1,为了和计算机沟通,你也得认识0和1 优点:执行效率快 缺点:普通人根本就写不了这种代码,开发效率低 汇编语言 他还 ...

  5. 如何 dump jvm 内存及线程栈

    1. dump jvm 内存 命令格式: jmap -dump:format=b,file=dump_file_name pid举例:dump pid 为 3239 的 java 进程的内存到 aa. ...

  6. python实现单线程多任务非阻塞TCP服务端

    代码 # coding:utf- from socket import * # .创建服务器socket sock = socket(AF_INET, SOCK_STREAM) # .绑定主机和端口 ...

  7. MATLAB 曲线形状,粗细,颜色使用大全

    通过改变R-G-B 的值改变线条的颜色: $$\tt\Large plot(x,y,'Color',[R~~G~~B]);$$ 通过改变$c\in[1,+\infty)$的值改变线条的粗细 $$\tt ...

  8. jquery 判断浏览器版本

    如果你也是Jquery最初的使用者,那么你一定经历过这样判断浏览器的时代:$.browser.msie && $.browser.version,你目前使用的组件里可能还有应用.但是J ...

  9. CRM创建BP(END USER)

    FUNCTION ZCRM_BP_CRT. *"---------------------------------------------------------------------- ...

  10. Spring Boot Application

    spring boot默认已经配置了很多环境变量,例如,tomcat的默认端口是8080,项目的contextpath是“/”等等,spring boot允许你自定义一个application.pro ...