python lock, semaphore, event实现线程同步
lock 机制不管你是java, C#, 还是python都是常用的线程同步机制, 相比较C# 的锁机制, python的加锁显得比较简单, 直接调用threading 标准库的lock 就可以了. python 的 lock类有两个函数, 分别是acquire 函数以及 release 函数, 前者起到锁定的作用, 将状态设置为锁定状态, 后者则是解锁, 将状态设置为未锁定状态. 我们看看代码:
# python 多线程同步 lock
import threading
from time import sleep num = 0
lock = threading.Lock() def func(st):
global num
print(threading.currentThread().getName() + ' try to acquire the lock')
if lock.acquire(): # 将状态修改为locked
print(threading.currentThread().getName() + ' acquire the lock.')
print(threading.currentThread().getName() + " :%s" % str(num))
num += 1
# sleep(st)
print(threading.currentThread().getName() + ' release the lock.')
lock.release() # 将状态修改为unlocked t1 = threading.Thread(target=func, args=(8,))
t2 = threading.Thread(target=func, args=(4,))
t3 = threading.Thread(target=func, args=(2,))
t1.start()
t2.start()
t3.start()
我们开了三个线程去调用同一个func 函数, 由于线程的不确定性, 如果没有加锁, 此时运行的话就会很混乱, 三个线程去执行同一个函数, 如果涉及到了变量的数据变化更是坑!因此我们加了锁, 确保数据的正确性, 函数执行的顺序性!
semaphore 信号量机制在python 里面也很简单就能够实现线程的同步。如果对操作系统有一定的了解, 那么对操作系统的PV原语操作应该有印象, 信号量其实就是基于这个机制的.semaphore 类是threading 模块下的一个类, 主要两个函数: acquire 函数, release 函数这和lock 类的函数是一样的, 只不过功能不一样, semaphore 机制的acquire 函数的参数允许你自己设置最大的并发量, 就是说允许多少个线程来操作同一个函数或是变量, 同时执行一次就会递减一次, release 函数则是递增, 如果计数到了0, 则阻塞起线程, 不再允许线程访问该方法或是变量.
# python 多线程同步 semaphore
import threading # 初始化信号量数量...当调用acquire 将数量置为 0, 将阻塞线程等待其他线程调用release() 函数
semaphore = threading.Semaphore(2) def func():
if semaphore.acquire():
for i in range(5):
print(threading.currentThread().getName() + ' get semaphore')
semaphore.release()
print(threading.currentThread().getName() + ' release semaphore') if __name__ == '__main__':
for i in range(4):
t1 = threading.Thread(target=func)
t1.start()
我们一次允许两个线程同时执行函数, 这可以从截图看出来:
event 机制不仅能够实现线程间的通信, 也是实现线程同步的一个好方法。事件是线程之间通信的最简单的机制之一, 一个线程指示一个事件和其他线程等待它.
event.py 是threading 模块下的一个类, 相比较前面两个机制, 这个类提供了四个方法, 分别是 is_set() 函数, set() 函数, clear() 函数, wait() 函数.
is_set判断事件管理标志是不是为true, 只有为true时, 才会返回
set 将标志设置为true
clear 将标志设置为flase
wait 等到标志为true时, 才会停止阻塞线程
import logging
import threading
import time # 打印线程名以及日志信息
logging.basicConfig(level=logging.DEBUG, format="(%(threadName)-10s : %(message)s", ) def wait_for_event_timeout(e, t):
"""Wait t seconds and then timeout"""
while not e.isSet():
logging.debug("wait_for_event_timeout starting")
event_is_set = e.wait(t) # 阻塞, 等待设置为true
logging.debug("event set: %s" % event_is_set)
if event_is_set:
logging.debug("processing event")
else:
logging.debug("doing other work") e = threading.Event() # 初始化为false
t2 = threading.Thread(name="nonblock", target=wait_for_event_timeout, args=(e, 2))
t2.start()
logging.debug("Waiting before calling Event.set()")
# time.sleep(7)
e.set() # 唤醒线程, 同时将event 设置为true
logging.debug("Event is set")
python lock, semaphore, event实现线程同步的更多相关文章
- python类库32[多进程同步Lock+Semaphore+Event]
python类库32[多进程同步Lock+Semaphore+Event] 同步的方法基本与多线程相同. 1) Lock 当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突. imp ...
- Python并行编程(三):线程同步之Lock
1.基础概念 当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码.bug等异常行为. 竞争条件最简单的解决方法是使用锁.锁的操 ...
- Python多线程(2)——线程同步机制
本文介绍Python中的线程同步对象,主要涉及 thread 和 threading 模块. threading 模块提供的线程同步原语包括:Lock.RLock.Condition.Event.Se ...
- Python并行编程(五):线程同步之信号量
1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...
- [b0034] python 归纳 (十九)_线程同步_条件变量
代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...
- [b0031] python 归纳 (十六)_线程同步_锁
# -*- coding: utf-8 -*- """ 学习 多线程同步 使用锁 threading.Lock() 逻辑: 2 个线程,操作同一个整型变量,一个加法,另外 ...
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...
- Python并行编程(七):线程同步之事件
1.基本概念 事件是线程之间用于通讯的对象.有的线程等待信号,有的线程发出信号.基本上事件对象都会维护一个内部变量,可以通过set方法设置为true,也可以通过clear方法设置为false.wait ...
- Python并行编程(四):线程同步之RLock
1.基本概念 如果想让只有拿到锁的线程才能释放该锁,那么应该使用RLock()对象.当需要在类外面保证线程安全,又要在类内使用同样方法的时候RLock()就很使用. RLock叫做Reentrant ...
随机推荐
- OpenCV相机标定
标签(空格分隔): Opencv 相机标定是图像处理的基础,虽然相机使用的是小孔成像模型,但是由于小孔的透光非常有限,所以需要使用透镜聚焦足够多的光线.在使用的过程中,需要知道相机的焦距.成像中心以及 ...
- 高仿腾讯QQ即时通讯IM项目
前言:其实这个项目早就开发完成了,在本人的github上,本来没打算写成博客的形式,因为一个项目要写出来要花很久,但是最近看到很多 人在我的github上download后随意发布到网上,本来上传到g ...
- Java基础---Java---IO流-----BufferedReader、BufferedWriter、缓冲区、装饰设计模式及和继承的区别
IO流 IO流用来处理设备之间的数据传输 java对数据的操作是过流的方式 流按操作数据分为两种:字节流与字符流 流按流向分为:输入流,输出流. IO流常用基类 字节流的抽象基类:InputStrea ...
- 头部——MimeHeaders
http协议的请求头部更像一个键值对,例如Content-Length : 123,前面为键后面为值,表示文本长度为123.对于若干个头部在请求对象中被封装成MimeHeaders对象,MimeHea ...
- 定制Maven原型生成项目
1自定义原型 1.1创建原型项目 要定制自己的原型,首先就要创建原型项目来进行定制: mvnarchetype:create -DgroupId=com.cdai.arche -DartifactId ...
- MariaDB存储引擎
MariaDB存储引擎 存储引擎就是指表的类型.数据库的存储引擎决定了表在计算机中的存储方式.存储引擎的概念是MariaDB的特点,而且是一种插入式的存储引擎概念.这决定了MariaDB数据库中的表可 ...
- Eclipse中查看没有源码的Class文件的方法
本文地址:http://blog.csdn.net/sushengmiyan/article/details/18798473 本文作者:sushengmiyan 我们在使用Eclipse的时候,经常 ...
- Spark Streaming + Flume整合官网文档阅读及运行示例
1,基于Flume的Push模式(Flume-style Push-based Approach) Flume被用于在Flume agents之间推送数据.在这种方式下,Spark Stre ...
- μC/OS-II与RT-Thread对比——任务调度
在任务调度器的实现上,μC/OS-II和RT-Thread都采用了位图调度(bitmap scheduling),任务优先级的值越小则代表具有越高的优先级,主要区别在于实现形式,是采用多 ...
- 【翻译】如何创建Ext JS暗黑主题之一
原文:How to Create a Dark Ext JS Theme– Part 1 概述 我是不是都要演示我的Spotifinder Ext JS应用程序.它是一个很酷的应用程序,可连接到Las ...