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 ...
随机推荐
- 【问题汇总】ScrollView嵌套GridView的问题
在开发中遇到了ScrollView嵌套GridView的情况,由于这两款控件都自带滚动条,当它们碰到一起的时候便会出问题,即GridView会显示不全. 解决办法,自定义一个GridView控件. [ ...
- Android项目开发填坑记-Fragment的onBackPressed
Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...
- Description Resource Path Location Type AndroidManifest.xml file missing!
这个问题又找了好久.国内回答的确不敢恭维. 本回答来自谷歌: This is build issue. Go to Menu in eclipse, Project>clean then P ...
- 高通8x12平台开机画面制作工具
你可能在网上看到很到关于手动更换手机开机图片的文章,想想自己的开机画面是小两口,好基友的照片多么个性啊.但是你有没有发现,网上下载的什么"一键生成"之类的,在你的手机上不能用啊,( ...
- iOS中类单例方法的一种实现
在Cocos2D编程中,很多情况我们需要类只生成一个实例,这称之为该类的单例类. 一般我们在类中这样实现单例方法: +(instancetype)sharedInstance{ static Foo ...
- Chapter 1 Securing Your Server and Network(12):保护链接服务器
原文出处:http://blog.csdn.net/dba_huangzj/article/details/38438363,专题目录:http://blog.csdn.net/dba_huangzj ...
- 谈谈Ext JS组件之引子
Ext JS组件,对于Ext JS开发人员来说,应当不会陌生,毕竟做开发,都必须与它打交道.对于这样一个大家都熟悉的东西,为什么要用一个专题的形式来写呢?是否有这方面的需要?还不如去写点使用技巧? 确 ...
- 2016 苹果全球开发者大会(WWDC)
纵观WWDC 2016开发者大会的全部内容,尽管本次大会没有那些新的产品发布,不过能让各位果粉的肾留到秋天,那也是苹果公司对各位果粉的关爱啊.但是对iOS开发者而言,新发布的技术还是比较不错的.主要内 ...
- ORA-04091错误原因与解决方法
最近工作中写了一触发器报错:ORA-04091:table XX is mutating, trigger/function may not see it. 下面通过官方文档及网友提供资料分析一下错 ...
- 17_Android中Broadcast详解(有序广播,无序广播)最终广播,Bundle传递参数,传递参数的时候指定权限
1 Broadcast是Android中的四大组件之一,他的用途很大,比如系统的一些广播:电量低.开机.锁屏等一些操作都会发送一个广播. 2 广播被分为两种不同的类型:"普通广播( ...