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. vim 文本替换讲解

    在VIM中进行文本替换: 1. 替换当前行中的内容: :s/from/to/ (s即substitude) :s/from/to/ : 将当前行中的第一个from,替换成to.如果当前行含有多个 fr ...

  2. Spring boot 去除URL 里的 JSESSIONID

    方法一 application.yml 里设置 server: port: 80 servlet: session: tracking-modes: cookie cookie: http-only: ...

  3. HTML5中的article和section的区别

    HTML5中的article和section的区别 一.总结 一句话总结: article和section都相当于语义化后的div,article强调独立性,section强调分段或者分块 1.art ...

  4. 用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan

    一个工具的逻辑得足够完善.意义足够重大,才有资格发在NG上. A gene-based association method for mapping traits using reference tr ...

  5. Jar hell问题以及解放方法

    当一个类或一个资源文件存在多个jar中,就好存在jar hell问题 可以通过以下代码来诊断问题:

  6. chrome下载提示网络错误

    问题背景:项目开发测试阶段出现该问题. 复现:开发调试过程中一直没有问题,本地下载excel.Word.pdf 都完美,但是在服务部署到服务器之后,测试环境的chrome就总是下载失败,提示网络错误. ...

  7. xhr.js:108 Refused to set unsafe header "Cookie"

    https://stackoverflow.com/questions/7210507/ajax-post-error-refused-to-set-unsafe-header-connection/ ...

  8. Android访问WCF服务

    原文链接:http://www.cnblogs.com/VinC/archive/2011/02/24/1964049.html 本章目的: 用Wcf建立可以上Android可以访问的数据服务, 数据 ...

  9. ubuntu redis config IP password

    ubuntu Redis安装测试.设置用户名密码 - zhangaik的博客 - CSDN博客 https://blog.csdn.net/zhangaik/article/details/79279 ...

  10. markdown如何在表格内换行?

    答:使用<br>即可在表格内换行