由线程遗留下的问题:GIL导致多个线程不能真正的并行,CPython中多个线程不能并行

单线程实现并发:切换+保存状态

  第一种方法:使用yield,yield可以保存状态。yield的状态保存与操作系统保存线程状态很像,但是yield是代码级控制的,更更轻量级。

# 两个计算任务一个采用生成器切换并发执行  一个直接串行调用
import time
def task1():
a =
for i in range():
a += i
yield def task2():
g = task1()
b =
for i in range():
b +=
next(g)
s = time.time()
task2()
print("并发执行时间",time.time()-s) # 单线程下串行执行两个计算任务 效率反而比并发高 因为并发需要切换和保存
def task1():
a =
for i in range():
a += i
def task2():
b =
for i in range():
b +=
s = time.time()
task1()
task2()
print("串行执行时间",time.time()-s)

可以看出,对于纯计算任务而言,单线程并发反而使效率降低。而且使用yield来切换使得代码结构混乱。

  第二种方法:使用greenlet模块,仅仅是对yield在封装。依然不能对检测IO操作。

import greenlet
def task1(name):
print("%s task1 run1" % name)
g2.switch(name) # 切换至任务2
print("task1 run2")
g2.switch() # 切换至任务2 def task2(name):
print("%s task2 run1" % name)
g1.switch() # 切换至任务1
print("task2 run2") g1 = greenlet.greenlet(task1)
g2 = greenlet.greenlet(task2)
g1.switch("jerry") # 为任务传参数

  第三种办法:协程

  协程: 指的是一个线程完成并发执行,协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的 

  强调:
  1. python的线程始于内核级别的,即由操作系统控制调度(遇到IO或执行事件过长就会被迫交出CPU执行权限,切换到其他线程)
  2. 单线程内开启协程,一旦遇到IO,就会从应用程序级别控制切换,以此来提升效率

  优点:

  1. 协程的切换开销更小,属于程序级别的切换,更加轻量级

  2. 单线程内就可以实现并发的效果,最大限度的利用CPU

  缺点:

  1. 协程本质是单线程并发,无法利用多核,可以是一个程序开多个进程,每个进程内开启多个线程,每个线程内开启协程

  2. 一旦协程遇到阻塞,将会阻塞整个线程

  

  在CPython中,如果是计算密集型,使用协程是无法提高效率,反而因为切换任务导致效率较低,只能靠进程。IO密集型 多线程会比多进程效率高,因为多线程开销比多进程小的多。

  使用模块:gevent,gevent既可以单线程实现并发,又可以检测IO操作
import gevent
import time
from gevent import monkey # 导入monkey补丁
monkey.patch_all() # 打补丁 def task1():
print("task1 run")
# gevent.sleep()
time.sleep()
print("task1 over") def task2():
print("task2 run")
# gevent.sleep()
time.sleep()
print("task2 over") g1 = gevent.spawn(task1)
g2 = gevent.spawn(task2)
# g1.join()
# g2.join()
gevent.joinall([g1,g2])
  需要注意:
  1. 协程执行时必须对协程对象调用join函数(join让主线程等待协程任务完成,因为主线程一旦结束,协程任务就不执行了。反过来说 要保证协程任务正常执行结束 必须保证主线程没有结束)
  2. 如果有多个任务,随便调用哪一个的join都会并发执行所有任务,但是需要注意如果有一个存在IO操作的任务没有被join,该任务将无法正常执行完毕。
  3. monkey补丁的原理,把原始的阻塞模块替换为修改后的非阻塞模块,来实现IO自定切换,所以打补丁的位置尽量要放在导入阻塞模块之前

python并发编程之协程知识点的更多相关文章

  1. 32 python 并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  2. 四 python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  3. python并发编程之协程(实践篇)

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对于单线程下,我们不可避免程序中出现io操作,但如果我们 ...

  4. 第十篇.5、python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  5. 第 12 章 python并发编程之协程

    一.引子 主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只用一个)情况下实现并发,并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作 ...

  6. 37、python并发编程之协程

    目录: 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本节的主题是基于单线程来 ...

  7. python 并发编程之协程

    一.协程 协程: 单线程下的并发,又称 微线程.协程是一种用户态的的轻量级线程,即协程是由用户程序自己控制调度的. ​ 协程的本质就是在单线程下,由用户自己控制一个任务,遇到 io 阻塞就切换另外一个 ...

  8. python并发编程之协程

    ---恢复内容开始--- 一.join方法 (1)开一个主线程 from threading import Thread,currentThread import time def walk(): p ...

  9. python全栈开发从入门到放弃之socket并发编程之协程

    一.为什么会有协程 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情 ...

随机推荐

  1. (摘)C#生成随机数的三种方法

    随机数的定义为:产生的所有数字毫无关系. 在实际应用中很多地方会用到随机数,比如需要生成唯一的订单号. 在C#中获取随机数有三种方法: 一.Random 类 Random类默认的无参构造函数可以根据当 ...

  2. 前端入门21-JavaScript的ES6新特性

    声明 本篇内容全部摘自阮一峰的:ECMAScript 6 入门 阮一峰的这本书,我个人觉得写得挺好的,不管是描述方面,还是例子,都讲得挺通俗易懂,每个新特性基本都还会跟 ES5 旧标准做比较,说明为什 ...

  3. Odoo:全球第一免费开源ERP库龄表的简单实现方法(无需二开)

    问题背景 希望查看库龄超过30天的货物,该如何实现?此种简单数据查询需要二开吗? 解决方案 方法一:Stock Quant列表视图增加过滤器 <filter string="库龄超30 ...

  4. Github 快速建库上传本地代码

    1 github.com网页端先建好一个空库 2 本地对这个库进行 git clone 3 向本地库中添加已完成文件 4 运行如下命令 git add . (注:别忘记后面的.,此操作是把Test文件 ...

  5. Vue与React两个框架的区别对比

    简单介绍 React--Facebook创建的JavaScript UI框架.它支撑着包括Instagram在内的大多数Facebook网站.React与当时流行的jQuery,Backbone.js ...

  6. Java日期的一些基本处理

    今天工作中用到一些日期的处理.这里做一点浅显的整理. 1.日期的加减: 日期加减一般用到Calendar这个类比较好.这样不用处理12月加一个月和28.30.31.加一天等问题 String last ...

  7. 在项目管理中如何保持专注,分享一个轻量的时间管理工具【Flow Mac版 - 追踪你在Mac上的时间消耗】

    在项目管理和团队作业中,经常面临的问题就是时间管理和优先级管理发生问题,项目被delay,团队工作延后,无法达到预期目标. 这个仿佛是每个人都会遇到的问题,特别是现在这么多的内容软件来分散我们的注意力 ...

  8. MyDAL - .UpdateAsync() 之 .Set() 使用

    索引: 目录索引 一.API 列表 1.Set<M, F>(Expression<Func<M, F>> propertyFunc, F newVal) 如: .S ...

  9. Pycharm安装并配置jupyter notebook

    Pycharm安装并配置jupyter notebook Pycharm安装并配置jupyter notebook 一: 安装命令jupyter: pip install jupyter 如果缺少依赖 ...

  10. 搭建Hadoop的环境

    准备实验的环境: 1.安装Linux.JDK 2.配置主机名.免密码登录 3.约定:安装目录:/usr/local/bin 安装: 1.解压 : tar -zxvf hadoop-2.7.7.tar. ...