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. ch341a编程器写操作超时失败

    当点击自动编写‘提示写操作超时失败’要怎么样才能解决,下面我给大家分享一下!   方法/步骤     首先我们点击操作   选择操作选项   看看箭头所指的几个地方是不是都没打上勾   我们把这几个地 ...

  2. NPAPI插件开发详细记录:用VS2010开发NPAPI插件步骤<转>

    原帖地址:https://blog.csdn.net/z6482/article/details/7660748 ------------------------------------------- ...

  3. JVM 数组创建的本质

    1.创建数组 创建一个MyParent4[] 数组 public class MyTest4 { public static void main(String[] args) { MyParent4[ ...

  4. PHP课程环境安装总结文档

    phpStudy的安装 1.找一个硬盘根目录,比如这里我使用E盘,在E盘根目录创建一个php的文件夹,进入php文件夹,如下图所示 2.在步骤1的php文件夹下再建立一个文件夹php_dev,如下图所 ...

  5. Unexpected token o in JSON at position 1 报错原因

    写在前面的话这个问题在之前做项目时碰到过一次,当时按照网上的做法,去掉JSON.parse()这一层转换后就没有这个报错了,数据也能正常使用,就没多想,也没深究是什么原因. 可是这次又碰到了,所以这次 ...

  6. java/spring boot/dubbo/spring cloud/微服务/SOA/分布式经典电子书籍pdf下载

    微服务系列 官方文档是最好的资料了. spring cloud官方文档:https://cloud.spring.io/spring-cloud-static/Greenwich.RELEASE/si ...

  7. Python 设计模式之建造者模式 Builder Pattern

    #引入建造者模式 肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐. 比如 套餐1:鸡翅,至尊虾汉堡,可乐,薯条 套餐2:鸡 ...

  8. Kotlin 之操作符重载

    Kotlin 之操作符重载   参考: kotlin in action kotlin 官方参考文档 运算符重载 Kotlin允许我们为自己的类型提供预定义的一组操作符实现(这些操作符都对应的成员函数 ...

  9. Access与SQL中的IsNull(),IS NULL的区别

    Access也有IsNull函数,但意义和参数却和T-SQL中的不同. 在T-SQL(也就是SQL Server所支持的SQL语言)中,IsNull的作用是把空值替代成指定的值.然而在Access中, ...

  10. INTEL 7代CPU I5 7500 集显HD630 WIN7 64位

    HD630 在WIN7 下的硬件ID  (在设备管理器 - 显卡 - 属性 中查看): PCI\VEN_8086&DEV_5912&SUBSYS_D0001458&REV_04 ...