9.14 线程Event

connect线程执行到event.wait()时开始等待,直到check线程执行event.set()后立即继续线程connect

from threading import Event,current_thread,Thread
import time
event=Event()
def check():
print('%s 正在检测服务是否正常....' %current_thread().name)
time.sleep(3)
event.set()

def connect():
print('%s 等待连接...' %current_thread().name)
event.wait()
print('%s 开始连接...' % current_thread().name)

if __name__ == '__main__':
t1=Thread(target=connect)
t2=Thread(target=connect)
t3=Thread(target=connect)

c1=Thread(target=check)

t1.start()
t2.start()
t3.start()
c1.start()

connect线程执行到event.wait(1)时开始等待1秒,count计数+1,如果到check线程执行event.set()前已经4秒,则终止线程connect,否则event.is_set() is True ,立即继续线程connect

from threading import Event,current_thread,Thread
import time
event=Event()
def check():
print('%s 正在检测服务是否正常....' %current_thread().name)
time.sleep(5)
event.set()

def connect():
count=1
while not event.is_set(): #event是否被set过,是返回True,否返回False
if count == 4:
print('尝试的次数过多,请稍后重试')
return
print('%s 尝试第%s次连接...' %(current_thread().name,count))
event.wait(1)
count+=1
print('%s 开始连接...' % current_thread().name)

if __name__ == '__main__':
t1=Thread(target=connect)
t2=Thread(target=connect)
t3=Thread(target=connect)

c1=Thread(target=check)

t1.start()
t2.start()
t3.start()
c1.start()

9.15 协程

协程:是单线程下的并发,又称微线程,纤程。一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

  1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到i/o或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行)

  2. 单线程内开启协程,一旦遇到i/o,就会从应用程序级别(而非操作系统)控制切换到其他任务,以此来提升效率(非i/o操作的切换与效率无关)

  3. 对比操作系统控制线程的切换,用户在单线程内控制协程的切换

  优点:
1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
2. 单线程内就可以实现并发的效果,最大限度地利用cpu
   
缺点:
1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程

9.151 greenlet模块

 from greenlet import greenlet
import time def eat(name):
print('%s eat 1' %name)
#time.sleep(30) 遇到i/o不能自动切换
g2.switch('alex')
print('%s eat 2' %name)
g2.switch()
def play(name):
print('%s play 1' %name)
g1.switch()
print('%s play 2' %name) g1=greenlet(eat)
g2=greenlet(play) g1.switch('egon') # egon eat 1 alex play 1 egon eat 2 alex play 2

9.152 gevent模块

import gevent

def eat(name):
print('%s eat 1' %name)
gevent.sleep(5) #只检测gevent的i/o
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
gevent.sleep(3)
print('%s play 2' %name)

g1=gevent.spawn(eat,'egon') #异步提交任务
g2=gevent.spawn(play,'alex')

# gevent.sleep(100)
# g1.join()
# g2.join() # joinall等待任务执行完毕再结束线程
gevent.joinall([g1,g2]) # egon eat 1 alex play 1 alex play 2 egon eat 2
from gevent import monkey;monkey.patch_all()#标记所有(包括time等)的i/o
import gevent
import time

def eat(name):
print('%s eat 1' %name)
time.sleep(5) #time的i/o也可以检测
print('%s eat 2' %name)
def play(name):
print('%s play 1' %name)
time.sleep(3)
print('%s play 2' %name)

g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex')

# gevent.sleep(100)
# g1.join()
# g2.join()
gevent.joinall([g1,g2]) # egon eat 1 alex play 1 alex play 2 egon eat 2

验证协程的假名:

from gevent import monkey;monkey.patch_all()#标记所有time等的i/o
from threading import current_thread
import gevent
import time

def eat():
print('%s eat 1' %current_thread().name)
time.sleep(5)
print('%s eat 2' %current_thread().name)
def play():
print('%s play 1' %current_thread().name)
time.sleep(3)
print('%s play 2' %current_thread().name)

g1=gevent.spawn(eat)
g2=gevent.spawn(play)

# gevent.sleep(100)
# g1.join()
# g2.join()
print(current_thread().name)#MainThread
gevent.joinall([g1,g2]) #DummyThread-1 eat 1 DummyThread-2 play 1 DummyThread-2 play 2 DummyThread-1 eat 2

9.153 基于协程实现并发的套接字通信

服务端:

from gevent import monkey,spawn;monkey.patch_all()#标记所有time等的i/o
from threading import Thread
from socket import *

def talk(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()

def server(ip,port,backlog=5):
s = socket()
s.bind((ip,port))
s.listen(backlog)

while True:
conn, addr = s.accept()
print(addr) g=spawn(talk,conn) # 通信
s.close()

if __name__ == '__main__':
spawn(server,'127.0.0.1',8080).join()
# server(('127.0.0.1',8080))

客户端:

from threading import Thread,current_thread
from socket import *
import os

def client():
client = socket()
client.connect(('127.0.0.1', 8080))

while True:
data = '%s hello' % current_thread().name
client.send(data.encode('utf-8'))
res = client.recv(1024)
print(res.decode('utf-8'))

if __name__ == '__main__':
for i in range(1000):
t=Thread(target=client)
t.start()

python 之 并发编程(线程Event、协程)的更多相关文章

  1. python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

  2. 15.python并发编程(线程--进程--协程)

    一.进程:1.定义:进程最小的资源单位,本质就是一个程序在一个数据集上的一次动态执行(运行)的过程2.组成:进程一般由程序,数据集,进程控制三部分组成:(1)程序:用来描述进程要完成哪些功能以及如何完 ...

  3. Python并发编程——多线程与协程

    Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线 ...

  4. Python并发编程系列之协程

    1 引言 协程是近几年并发编程的一个热门话题,与Python多进程.多线程相比,协程在很多方面优势明显.本文从协程的定义和意义出发,结合asyncio模块详细讲述协程的使用. 2 协程的意义 2.1 ...

  5. python中进程、线程、协程简述

    进程 python中使用multiprocessing模块对进程进行操作管理 进程同步(锁.信号量.事件) 锁 —— multiprocessing.Lock 只要用到了锁 锁之间的代码就会变成同步的 ...

  6. Python3 与 C# 并发编程之~ 协程篇

      3.协程篇¶ 去年微信公众号就陆陆续续发布了,我一直以为博客也汇总同步了,这几天有朋友说一直没找到,遂发现,的确是漏了,所以补上一篇 在线预览:https://github.lesschina.c ...

  7. Python之进程、线程、协程篇

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

  8. python系列7进程线程和协程

    目录 进程 线程 协程  上下文切换 前言:线程和进程的关系图 由下图可知,在每个应用程序执行的过程中,都会去产生一个主进程和主线程来完成工作,当我们需要并发的执行的时候,就会通过主进程去生成一系列的 ...

  9. Python之进程、线程、协程

    进程和线程的目的 进程和线程目的是为了:提高执行效率 现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统. 什么叫“多任务“呢?简单地说,就是操作系 ...

  10. python基础===进程,线程,协程的区别(转)

    本文转自:http://blog.csdn.net/hairetz/article/details/16119911 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自 ...

随机推荐

  1. <英狼> 团队作业2--王者光耀

    队员 陶俊宇_031702113 卞永亨_031702229 唐怡_031702109 Github 吉哈---King-Shines

  2. go中的方法以及自定义类型代码示例

    package main import "fmt" type user struct { name string age int sex string } type admin s ...

  3. ubuntu之路——day8.4 Adam自适应矩估计算法

    基本上讲,Adam就是将day8.2提到的momentum动量梯度下降法和day8.3提到的RMSprop算法相结合的优化算法 首先初始化 SdW = 0 Sdb = 0 VdW = 0 Vdb = ...

  4. Windows 实例远程桌面报错“没有远程桌面授权服务器可以提供许可证”

    参考阿里云帮助文档: https://help.aliyun.com/knowledge_detail/40859.html?spm=5176.10695662.1996646101.searchcl ...

  5. SOA面向服务体系架构

    SOA概念 1.什么是SOA 面向服务的体系结构(Service-Oriented Architecture,SOA)是一个组件模型. 它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的 ...

  6. Qt *.pro工程文件 详解

    先介绍一下QT中关于项目的相关介绍 app - 建立一个应用程序的makefile.这是默认值,所以如果模板没有被指定,这个将被使用. lib - 建立一个库的makefile. vcapp - 建立 ...

  7. IDEA Git 修改后的文件无法Commit

    转自:https://blog.csdn.net/moneyshi/article/details/81298861 因对IDEA使用不熟,在使用和配置GIT的时候,可能哪里配置错误,导致我一直无法使 ...

  8. maven项目新检出后不编译爬坑记 及 mvn clean package报错 WagonTransporterFactory: java.util.NoSuchElementException 异常【我】

    从SVN新检出一个maven项目,配置好后,发现项目无法编译(只有一个test包中的代码显示编译报错,其他所有包中的代码都不编译,也不报错), 先注释掉报错的test包中的所有内容, 用Eclipse ...

  9. bat函数调用 带返回值

    bat 脚本之 使用函数 摘自:https://blog.csdn.net/peng_cao/article/details/73999076 综述 bat函数写法 bat函数调用 bat函数返回值 ...

  10. RabbitMQ 入门教程(PHP版) 使用rabbitmq-delayed-message-exchange插件实现延迟功能

    延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...