1、基础

# 进程 启动多个进程 进程之间是由操作系统(时间片轮转)负责调用
# 线程 启动多个线程 真正被CPU执行的最小单位是线程# 开启一个线程 创建一个线程 寄存器 堆栈# 关闭一个线程  等都需要时间
# 协程:本质上是一个线程# 能够在多个任务之间切换来节省一些IO时间# 协程切换也需要时间,但是远远小于线程进程开销时间
# 实现并发的手段

2 协程应用背景

import time
'''1'''
def consumer():  # 生成器函数print(123)while True:x=yieldprint('**',x)
c=consumer()  # c为生成器,此时函数并没有执行
next(c)
c.send(1)

程序执行顺序:

程序运行结果:

3 在一个程序上进行两个任务的切换

'''2 在一个程序上进行两个任务的切换'''
def consumer():  # 生成器函数while True:x=yieldtime.sleep(1)print('处理了数据',x)
def producer():c=consumer()next(c)for i in range(3):time.sleep(1)print('生产了数据:',i)c.send(i)
producer()

程序执行顺序:

程序运行结果:

4、协程切换:切换后接着执行-greenlet模块

'''3 协程切换:切换后接着执行'''
from greenlet import greenlet
# 真正的协程模块就是使用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()

程序执行顺序:

程序执行结果:

5 协程切换 gevent

# spawn(func) 大量生产
# join()
# .value 得到方法的返回值

例子1:

import geventdef eat():print('eating start')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() # 主线程等待g1结束
g2.join()  # 主线程等待g2结束

运行结果:

协程对time.sleep(1)不会有效果。只对gevent.sleep(1)有效果。除非用monkey模块。如下:

from gevent import monkey;monkey.patch_all()   # 有了这句代码,自动会把IO操作打包。否则就需要用gevent.sleep()
import gevent
def eat():print('eat:', threading.current_thread().getName()) #DummyThread-1假线程print('eating start')time.sleep(1) # IO事件print('eating end')
def play():print('play:', threading.current_thread().getName())print('playing start')time.sleep(1)  # IO事件print('playing end')
g1=gevent.spawn(eat)  # 开启一个协程
g2=gevent.spawn(play)
g1.join()
g2.join()

运行结果:

协程属于伪线程

6 同步和异步

# 进程和线程的状态切换是由操作系统完成
# 协程任务之间的切换是由程序(代码)完成。# 只有遇到协程模块能识别的IO操作的时候,程序才会进行任务切换,实现并发的效果#同步和异步:在高IO之间使用协程操作
# 协程 : 能够在一个线程中实现并发效果的概念# 能够规避一些任务中的IO操作# 在任务的执行过程中检测到IO就切换到其他任务
from gevent import monkey;monkey.patch_all()  # 必须写在import其他模块之前
import time
import gevent
def task():time.sleep(1)print(12345)
def sync():for i in range(10):task()
def async():g_lst=[]for i in range(10):g=gevent.spawn(task)g_lst.append(g)# for g in g_lst:g.join()gevent.joinall(g_lst)
sync()
async()

运行结果:

输出过程:先一秒一秒输出12345.输出四个后。同时输出5个12345

7 利用协程实现socket聊天

server模块:

import socket
from gevent import monkey;monkey.patch_all()
import gevent
def talk(conn):conn.send(b'hello')print(conn.recv(1024).decode('utf-8'))conn.close()
sk=socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
while True:conn,addr=sk.accept()gevent.spawn(talk,conn)
sk.close()

client模块:

import socket
sk=socket.socket()
sk.connect(('127.0.0.1',8080))
print(sk.recv(1024))
msg=input('>>>').encode('utf-8')
sk.send(msg)
sk.close()

运行结果:

进程,线程,协程个数关系

python并发编程6-协程相关推荐

  1. python并发编程之协程

    python并发编程之协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞 ...

  2. python并发编程:协程asyncio、多线程threading、多进程multiprocessing

    python并发编程:协程.多线程.多进程 CPU密集型计算与IO密集型计算 多线程.多进程与协程的对比 多线程 创建多线程的方法 多线程实现的生产者-消费者爬虫 Lock解决线程安全问题 使用线程池 ...

  3. python并发之协程_python并发编程之协程

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

  4. python 异步编程:协程与 asyncio

    文章目录 一.协程(coroutine) 1.1 协程的概念 1.2 实现协程的方式 二.asyncio 异步编程 2.1 事件循环 2.2 快速上手 2.3 运行协程 2.4 await 关键字 2 ...

  5. Java并发编程实战~协程

    Golang 是一门号称从语言层面支持并发的编程语言,支持并发是 Golang 一个非常重要的特性.在上一篇文章<44 | 协程:更轻量级的线程>中我们介绍过,Golang 支持协程,协程 ...

  6. 3-Go并发编程与协程Goroutine

    目录 一.并发编程 1 - 并行和并发 2 - 程序.进程.线程 3 - 进程并发 4 - 线程并发 5 - 线程同步 二.协程Coroutine 1 - 协程概念 2 - Go并发 3 - go程创 ...

  7. Python 异步编程之——协程

    1.总则 多进程可以实现真正的并行,但进程间无法进行直接通信且占用资源较多.多线程的使用代价相对多进程较小,但为了解决数据安全问题引入了锁的机制.这又使得多线程并发度降低,同时,使用锁还可能造成死锁. ...

  8. Go 分布式学习利器(17)-- Go并发编程之协程机制:Grountine 原理及使用

    文章目录 1. Thread VS Groutine 2. Groutine 调度原理 3. Groutine 示例代码 关于Go的底层实现还需要后续持续研究,文中如有一些原理描述有误,欢迎指证. 1 ...

  9. Golang并发编程-GPM协程调度模型原理及组成分析

    文章目录 一.操作系统的进程和线程模型 1.1.基础知识 1.2.KST/ULT 二.Golang的GPM协程调度模型 三.M的结构及对应关系 四.P的结构及状态转换 五.G的结构及状态转换 六.GP ...

  10. Python并发编程之线程池/进程池

    引言 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/销毁进程或者线程是非常消耗资源的,这个时候我 ...

最新文章

  1. 玩了一个人脸识别登录
  2. 我的node+express小例子
  3. 查看mysql 的配置文件位置_查看当前mysql使用的配置文件是哪个
  4. 200设备管理器找不到蓝牙_达尔优LK200蓝牙键盘,一键切换+支持三台设备+百元不到...
  5. atitit.jQuery Validate验证框架详解与ati Validate 设计新特性
  6. Java三种随机数生成方法
  7. golang——strconv包常用函数
  8. 美物理学家称摩尔定律将在十年内崩溃
  9. 【最短路】Walls
  10. C#基础知识五之abstract virtual关键字
  11. jfreeChart生成报表
  12. 人脸识别-论文阅读-ArcFace及其由来(SphereFace、CosFace)
  13. SQL 汉字转拼音函数(转)+将表中汉字转拼音
  14. 一个好用的 txt 小说阅读器(自用好用,目前没发现替代款)
  15. c#之toolstrip_toolstripcontainer_TopToolStripPanel
  16. centos7 gitlab14搭建完成后,无法访问的问题处理(“error“:“badgateway: failed to receive response: dial unix /var/opt)
  17. 计算机专业的单招大学排名,全国单招学校排名 单招哪个学校比较好
  18. c语言时钟报告,C语言时钟图形输出系统设计报告.doc
  19. 高仿 QQ 侧滑删除 Item 的效果
  20. 工具使用 - 开发、办公工具分享

热门文章

  1. JAVA WEB篇2——Servlet
  2. flash动画制作作品_flash施工动画制作应该展现哪些内容
  3. python怎么判断输入的是不是数字_如何在PYTHON里判断字符串是否为数字
  4. 带桭字的名字_男孩带官运大气的名字有气魄有能力-可爱点
  5. mysql内置加密函数_MySQL数据库内置加密函数总结
  6. mysql查询最小的id_Mysql查询表中最小可用id值的方法
  7. updatepanel失效怎么办_【点滴积累】解决jQuery绑定事件在updatepanel更新后失效的方法...
  8. Spring Cloud —— 负载均衡与 Ribbon 应用
  9. C语言存储编码输出,C语言怎么输出一个菱形
  10. 梯度、梯度法、python实现神经网络的梯度计算