python中实现并发的手段之 协程
几种实现并发的手段
进程
启动多个进程 进程之间是由操作系统负责调用
线程
启动多个线程 真正被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) producer()
通过greenlet模块实现的协程
真正的协程模块就是使用greenlet完成的切换
from greenlet import greenlet
def eat():
print('eating start')
g2.switch()
print('eating end')
g2.switch() def play():
print('playing start')
g1.switch()
print('playing end')
g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch()
通过genevt模块实现的协程
可以看出来,greenlet只能实现两个代码之间的切换,但是我们使用协程的主要原因是在IO请求时,达到非阻塞的作用,所以我们需要使用gevent模块来让代码可以遇到阻塞就自由的切换
from gevent import monkey;monkey.patch_all()
import time
import gevent
import threading
def eat():
print(threading.current_thread().getName())
print(threading.current_thread())
print('eating start')
time.sleep(1)
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)
g2 = gevent.spawn(play)
g1.join()
g2.join()
同步和异步的性能比较
进程和线程的任务切换由操作系统完成
协程任务之间的切换由程序(代码)完成,只有遇到协程模块能识别的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(10):
task(i) def async():
g_lst = []
for i in range(10):
g = gevent.spawn(task,i)
g_lst.append(g)
gevent.joinall(g_lst) # for g in g_lst:g.join() sync()
async()
什么时候可以使用协程??
在高IO的时候可以使用 例如爬虫, 爬虫需要请求很多url,使用协程可以让请求同时发出,而不会因为在等待一个url的请求响应而阻塞程序
不适用于高计算的环境, 因为在计算时cpu是一直工作的, 频繁的切换运行的程序,会白白增加切换程序的时间,导致计算效率下降
python中实现并发的手段之 协程的更多相关文章
- 深入浅析python中的多进程、多线程、协程
深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...
- Python 中的进程、线程、协程、同步、异步、回调
进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 一.上下文切换技术 简述 在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说 ...
- python中多线程,多进程,多协程概念及编程上的应用
1, 多线程 线程是进程的一个实体,是CPU进行调度的最小单位,他是比进程更小能独立运行的基本单位. 线程基本不拥有系统资源,只占用一点运行中的资源(如程序计数器,一组寄存器和栈),但是它可以与同属于 ...
- Python中的多进程、多线程和协程
本文中的内容来自我的笔记.撰写过程中参考了胡俊峰老师<Python程序设计与数据科学导论>课程的内容. 并发处理:多进程和多线程 前置 概念: 并发:一段时间内同时推进多个任务,但不一定要 ...
- Python、进程间通信、进程池、协程
进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...
- Python并发编程系列之协程
1 引言 协程是近几年并发编程的一个热门话题,与Python多进程.多线程相比,协程在很多方面优势明显.本文从协程的定义和意义出发,结合asyncio模块详细讲述协程的使用. 2 协程的意义 2.1 ...
- python并发编程之gevent协程(四)
协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...
- python并发编程之asyncio协程(三)
协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...
- Python中的并发
目录 Python并发 并发三种层次 协程 生成者消费者 新关键字 网络io 线/进程 例子 线程池 进程通信 并发池 future对象 executor对象 参考 Python并发 并发三种层次 个 ...
随机推荐
- TestFlight 的使用记载
TestFlight: TestFlight内测网上很多资料.大概是先打包,然后在App Store Connect 里添加测试员的邮箱地址. Testflight.top:公测要用到test ...
- MyBatisPlus忽略映射字段注解
MyBatisPlus忽略映射字段注解 @TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的. @TableField(exist = true):表示该 ...
- linux 防火墙 iptables 目录
linux iptables 防火墙简介 Linux 防火墙:Netfilter iptables 自动化部署iptables防火墙脚本
- 增加wamp64 PHP支持版本
1.停止WAMP服务器.2.下载要安装的PHP版本.下载Window版本的ZIP包啦:http://php.net/downloads.php.解压到 Wamp的安装目录C:\wamp64\bin\p ...
- PHP中new self()和new static()的区别探究
1.new static()是在PHP5.3版本中引入的新特性. 2.无论是new static()还是new self(),都是new了一个新的对象. 3.这两个方法new出来的对象有什么区别呢,说 ...
- nghttp2 和nginx的实践
主要参考https://bg2bkk.github.io/post/HTTP2%E7%9A%84%E5%AE%9E%E8%B7%B5%E8%BF%87%E7%A8%8B/,和https://fangp ...
- [Android] 转-RxJava+MVP+Retrofit+Dagger2+Okhttp大杂烩
原文url: http://blog.iliyun.net/2016/11/20/%E6%A1%86%E6%9E%B6%E5%B0%81%E8%A3%85/ 这几年来android的网络请求技术层出不 ...
- session删除
<?php session_start(); //删除session $_SESSION=array(); //删除客户端cookie中存储的sessionID值 if(isset($_COOK ...
- week_one-python基础 基本语法、流程控制
金角大王的紫金葫芦,python开发环境介绍链接:http://list.youku.com/albumlist/show/id_28961509.html # Author:larlly pytho ...
- DIV层的使用方法
1.可以判断你选择的样式是否存在用下边的方法(如果存在的话执行某个方法) if ($(this).hasClass('cur')) 2.这个方法可以查询一个页面中同样的div层总共有几个 var i= ...