python--线程同步原语
Threading模块是python3里面的多线程模块,模块内集成了许多的类,其中包括Thread,Condition,Event,Lock,Rlock,Semaphore,Timer等等。下面这篇文章主要通过案例来说明其中的Event和Segmaphore(Boundedsegmaphore)的使用。关于Lock的使用可以移步到我之前写的文章python同步原语--线程锁。
Event
Event类内部保存着一个flags参数,标志事件的等待与否。
Event类实例函数
1. set() 将flags设置为True,事件停止阻塞
2. clear() 将flags重新设置为False,删除flags,事件重新阻塞
3. wait() 将事件设置为等待状态
4.is_set()判断flags是否被设置,如果被设置返回True,否则返回False
(1)单个事件等待其他事件的发生
具体代码:
from time import ctime,sleep
event = Event() def event_wait():
print(ctime())
event.wait()
print('这是event_wait方法中的时间',ctime()) def event_set(n):
sleep(n)
event.set()
print('这是event_set方法中的时间', ctime()) thread1 = Thread(target=event_wait)
thread2 = Thread(target=event_set,args=(3,)) thread1.start()
thread2.start()
结果:
Sat Nov 17 10:01:05 2018
这是event_wait方法中的时间 Sat Nov 17 10:01:08 2018
这是event_set方法中的时间 Sat Nov 17 10:01:08 2018
(2)多个事件先后发生
下面以赛跑来作为例子。假设5条跑道上,每条跑道各有一名运动员,分别为ABCDE。
具体代码:
from threading import Event
from threading import Thread
import threading event = Event() def do_wait(athlete):
racetrack = threading.current_thread().getName()
print('%s准备就绪' % racetrack)
event.wait()
print('%s听到枪声,起跑!'%athlete) thread1 = Thread(target=do_wait,args=("A",))
thread2 = Thread(target=do_wait,args=("B",))
thread3 = Thread(target=do_wait,args=("C",))
thread4 = Thread(target=do_wait,args=("D",))
thread5 = Thread(target=do_wait,args=("E",)) threads = []
threads.append(thread1)
threads.append(thread2)
threads.append(thread3)
threads.append(thread4)
threads.append(thread5) for th in threads:
th.start() event.set() #这个set()方法很关键,同时对5个线程中的event进行set操作
结果:
Thread-1准备就绪
Thread-2准备就绪
Thread-3准备就绪
Thread-4准备就绪
Thread-5准备就绪
E听到枪声,起跑!
A听到枪声,起跑!
B听到枪声,起跑!
D听到枪声,起跑!
C听到枪声,起跑!
可以看出多个线程中event的set()是随机的,其内部的实现是因为一个notify_all()方法。这个方法会一次性释放所有锁住的事件,哪个线程先抢到线程运行的时间片,就先释放锁。
之所以能够只调用一个set()函数就可以实现所有event的退出阻塞,是因为event.wait()是在线程内部实现的,而set()函数是在进程中调用,python多线程共享一个进程内存空间。如果是在不同进程中调用这两个函数则无法实现。
BoundedSegmaphore
如果在主机执行IO密集型任务的时候再执行这种短时间内完成大量任务(多线程)的程序时,计算机就有很大可能会宕机。
这时候就可以为这段程序添加一个计数器(counter)功能,来限制一个时间点内的线程数量。当每次进行IO操作时,都需要向segmaphore请求资源(锁),如果没有请求到,就阻塞等待,请求成功才就像执行任务。
BoundedSegmaphore和Segmaphore的区别
BoundedSegmaphore请求的锁数量固定为传入参数,而Segmaphore请求的锁数量可以超过传入的参数。
主要函数:
1. acquire() 请求锁
2. release() 释放锁
下面以一个租房的例子来说明这种固定锁数量的机制。假设一家小公寓有6间房,原本有2个住户在住着。
具体代码实现:
from threading import BoundedSemaphore,Lock,Thread
from time import sleep
from random import randrange lock = Lock()
num = 6
hotel = BoundedSemaphore(num) def logout():
lock.acquire()
print('I want to logout')
print('A customer logout...')
try:
hotel.release()
print('Welcome again')
except ValueError:
print('Sorry,wait a moment.')
lock.release() def login():
lock.acquire()
print('I want to login')
print('A customer login...')
if hotel.acquire(False):
print('Ok,your room number is...')
else:
print('Sorry,our hotel is full')
lock.release() #房东
def producer(loops):
for i in range(loops):
logout()
print('还剩%s' % hotel._value, '房间')
sleep(randrange(2))
#租客
def consumer(loops):
for i in range(loops):
login()
print('还剩%s' % hotel._value, '房间')
sleep(randrange(2))
def main():
print('Start')
room_num = hotel._value
print('The hotel is full with %s room'%room_num)
#原本有2个住户
hotel.acquire()
hotel.acquire()
thread1 = Thread(target=producer,args=(randrange(2,8),))
thread2 = Thread(target=consumer,args=(randrange(2,8),))
thread1.start()
thread2.start() if __name__ == '__main__':
main()
结果:
The hotel is full with 6 room
I want to logout
A customer logout...
Welcome again
还剩5 房间
I want to logout
A customer logout...
Welcome again
还剩6 房间
I want to login
A customer login...
Ok,your room number is...
还剩5 房间
I want to login
A customer login...
Ok,your room number is...
还剩4 房间
可以看出,房间数目永远不会超过6,因为_value值(BoundedSegmaphore内部的计数器counter)一定是传入的参数6。
python--线程同步原语的更多相关文章
- python线程同步原语--源码阅读
前面两篇文章,写了python线程同步原语的基本应用.下面这篇文章主要是通过阅读源码来了解这几个类的内部原理和是怎么协同一起工作来实现python多线程的. 相关文章链接:python同步原语--线程 ...
- C#并行编程-线程同步原语
菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...
- Python线程同步
线程执行 join与setDaemon 子线程在主线程运行结束后,会继续执行完,如果给子线程设置为守护线程(setDaemon=True),主线程运行结束子线程即结束: 如果join()线程,那么主线 ...
- Python 线程同步
#-*-coding:utf-8-*- '''如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性, 需要对多个线程进行同步. 线程同步所使用的的方法: Lock RLock ...
- Python 线程同步变量,同步条件,列队
条件变量同步 有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 ...
- Python 线程同步锁, 信号量
同步锁 import time, threading def addNum(): global num num -= 1 num = 100 thread_list = [] for i in ran ...
- python同步原语--线程锁
多线程锁是python多种同步原语中的其中一种.首先解析一下什么是同步原语,python因为GIL(全局解析锁)的缘故,并没有真正的多线性.另外python的多线程存在一个问题,在多线程编程时,会出现 ...
- Python多线程(2)——线程同步机制
本文介绍Python中的线程同步对象,主要涉及 thread 和 threading 模块. threading 模块提供的线程同步原语包括:Lock.RLock.Condition.Event.Se ...
- python——线程相关
使用python的threading中的Thread 下面是两种基本的实现线程的方式: 第一种方式———— #coding=utf-8 """ thread的第一种声明及 ...
- python多线程同步机制Semaphore
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Python 线程同步机制:Semaphore "" ...
随机推荐
- 学习笔记第六课 VB程序
VB程序的特殊地方在于: 前几课学的破解方法,诸如设置API断点,修改关键CALL的返回值,MESSAGEBOX断点等,这些对于VB程序都是无效的. 这节课是设置VB的API断点,绕过报错弹窗来破解. ...
- mysql 架构篇系列 2 复制架构一主一从搭建(异步复制)
一. 环境准备 1.1 主库环境(172.168.18.201) 环境 说明 查看脚本 操作系统版本 CentOS Linux release 7.4.1708 (Core) cat /etc/red ...
- [疑难杂症]__当你的Cortana搜索无法使用,显示纯白界面(ps:已解决).
前言 这个问题是在前不久解决关于我电脑点击屏幕上方快捷方式不久后出现的问题,之前并没有出现过这样的错误,但因为使用到的情况比较少,就一直没有去解决,但在一点时间后,发现没有Cortana搜索栏还是十分 ...
- centos7安装Wkhtmltopdf
从官网下载预编译版安装: wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12 ...
- 连接MySQL的10060错误:Can't connect to MySQL server on '*.*.*.*'(10060)
使用MySQL的图形界面管理工具Navicat for MySQL连接Mysql数据库时提示错误:Can't connect to MySQL server (10060) [出现该问题可能的原因:] ...
- Keras入门(二)模型的保存、读取及加载
本文将会介绍如何利用Keras来实现模型的保存.读取以及加载. 本文使用的模型为解决IRIS数据集的多分类问题而设计的深度神经网络(DNN)模型,模型的结构示意图如下: 具体的模型参数可以参考文章 ...
- .NET CORE 设置cookie以及获取cookie
使用我这个方式的前提是在mvc中,确认你安装了:Microsoft.AspNetCore.Mvc. 然后在继承了Controller的类型中使用我所说的方法. 直接使用即可,我是封装了方法供我自己使用 ...
- c#连接oracle数据库 DBHelper
闲着没事自己写了一个OracleHelper类,希望大神给点建议优化 using System; using System.Collections.Generic; using System.Linq ...
- [日常] PHP库函数fgetss的BUG
1. fgetss函数php官网的解释是: (PHP 4, PHP 5, PHP 7) fgetss — 从文件指针中读取一行并过滤掉 HTML 标记 2. 测试后出现的问题是: 当文本中有一行数据 ...
- webpack4 系列教程(十二):处理第三方JavaScript库
教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十二):处理第三方 JavaScript 库>原文地址.或者来我的小站看更多内容:godbm ...