Python多线程同步Lock、RLock、Semaphore、Event实例


Posted in Python onNovember 21, 2014

一、多线程同步

由于CPython的python解释器在单线程模式下执行,所以导致python的多线程在很多的时候并不能很好地发挥多核cpu的资源。大部分情况都推荐使用多进程。

python的多线程的同步与其他语言基本相同,主要包含:

Lock & RLock :用来确保多线程多共享资源的访问。
Semaphore : 用来确保一定资源多线程访问时的上限,例如资源池。 
Event : 是最简单的线程间通信的方式,一个线程可以发送信号,其他的线程接收到信号后执行操作。 

二、实例

1)Lock & RLock

Lock对象的状态可以为locked和unlocked

使用acquire()设置为locked状态;
使用release()设置为unlocked状态。

如果当前的状态为unlocked,则acquire()会将状态改为locked然后立即返回。当状态为locked的时候,acquire()将被阻塞直到另一个线程中调用release()来将状态改为unlocked,然后acquire()才可以再次将状态置为locked。

Lock.acquire(blocking=True, timeout=-1),blocking参数表示是否阻塞当前线程等待,timeout表示阻塞时的等待时间 。如果成功地获得lock,则acquire()函数返回True,否则返回False,timeout超时时如果还没有获得lock仍然返回False。

实例:(确保只有一个线程可以访问共享资源)

import threading

import time

 

num = 0

lock = threading.Lock()

 

def func(st):

    global num

    print (threading.currentThread().getName() + ' try to acquire the lock')

    if lock.acquire():

        print (threading.currentThread().getName() + ' acquire the lock.' )

        print (threading.currentThread().getName() +" :%s" % str(num) )

        num += 1

        time.sleep(st)

        print (threading.currentThread().getName() + ' release the lock.'  )        

        lock.release()

 

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()

结果:

Python多线程同步Lock、RLock、Semaphore、Event实例

RLock与Lock的区别是:RLock中除了状态locked和unlocked外还记录了当前lock的owner和递归层数,使得RLock可以被同一个线程多次acquire()。

2)Semaphore

Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

实例:(同时只有2个线程可以获得semaphore,即可以限制最大连接数为2):

import threading

import time
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')

        

        

for i in range(4):

  t1 = threading.Thread(target=func)

  t1.start()

结果:

Python多线程同步Lock、RLock、Semaphore、Event实例

3) Event

Event内部包含了一个标志位,初始的时候为false。
可以使用使用set()来将其设置为true;
或者使用clear()将其从新设置为false;
可以使用is_set()来检查标志位的状态;
另一个最重要的函数就是wait(timeout=None),用来阻塞当前线程,直到event的内部标志位被设置为true或者timeout超时。如果内部标志位为true则wait()函数理解返回。

实例: (线程间相互通信)

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)

      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()

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()

logging.debug("Event is set")

运行结果:

Python多线程同步Lock、RLock、Semaphore、Event实例

三、其他

1) 线程局部变量

线程局部变量的值是跟线程相关的,区别与全局的变量。使用非常简单如下:

mydata = threading.local()

mydata.x = 1

2)对Lock,semaphore,condition等使用with关键字代替手动调用acquire()和release()。

Python 相关文章推荐
Python序列之list和tuple常用方法以及注意事项
Jan 09 Python
python计算方程式根的方法
May 07 Python
Python对数据库操作
Mar 28 Python
PyQt5主窗口动态加载Widget实例代码
Feb 07 Python
Python处理CSV与List的转换方法
Apr 19 Python
python使用knn实现特征向量分类
Dec 26 Python
使用python读取.text文件特定行的数据方法
Jan 28 Python
python实现的config文件读写功能示例
Sep 24 Python
pytorch如何冻结某层参数的实现
Jan 10 Python
python网络编程:socketserver的基本使用方法实例分析
Apr 09 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
Apr 23 Python
Python更改pip镜像源的方法示例
Dec 01 Python
python多进程操作实例
Nov 21 #Python
Python多进程通信Queue、Pipe、Value、Array实例
Nov 21 #Python
Python多进程同步Lock、Semaphore、Event实例
Nov 21 #Python
Python multiprocessing.Manager介绍和实例(进程间共享数据)
Nov 21 #Python
Python pickle类库介绍(对象序列化和反序列化)
Nov 21 #Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
Nov 21 #Python
Python实现的下载8000首儿歌的代码分享
Nov 21 #Python
You might like
php关于array_multisort多维数组排序的使用说明
2011/01/04 PHP
PHP 多维数组的排序问题 根据二维数组中某个项排序
2011/11/09 PHP
mysql alter table命令修改表结构实例详解
2016/09/24 PHP
jQuery EasyUI API 中文文档 - PropertyGrid属性表格
2011/11/18 Javascript
用按钮控制iframe显示的网页实现方法
2013/02/04 Javascript
利用JS判断用户是否上网(连接网络)
2013/12/23 Javascript
js函数内变量的作用域分析
2015/01/12 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
2016/08/31 Javascript
强大Vue.js组件浅析
2016/09/12 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
原生js实现可爱糖果数字时间特效
2016/12/30 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
Vue实现购物车功能
2017/04/27 Javascript
学习使用Bootstrap输入框、导航、分页等常用组件
2017/05/11 Javascript
Vue关于数据绑定出错解决办法
2017/05/15 Javascript
Angular2使用jQuery的方法教程
2017/05/28 jQuery
JS实现简单抖动效果
2017/06/01 Javascript
React Native模块之Permissions权限申请的实例相机
2017/09/28 Javascript
vuejs使用axios异步访问时用get和post的实例讲解
2018/08/09 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
Python多进程通信Queue、Pipe、Value、Array实例
2014/11/21 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
python下10个简单实例代码
2017/11/15 Python
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
python贪吃蛇游戏代码
2020/04/18 Python
django框架面向对象ORM模型继承用法实例分析
2019/07/29 Python
python机器学习实现决策树
2019/11/11 Python
django下创建多个app并设置urls方法
2020/08/02 Python
全球最大的游戏市场:G2A
2018/07/05 全球购物
安德玛比利时官网:Under Armour比利时
2019/08/28 全球购物
高中毕业生自我鉴定范文
2013/09/26 职场文书
人事主管岗位职责说明书
2014/07/30 职场文书
2016年“5.12”护士节慰问信
2015/11/30 职场文书
关于元旦的广播稿2016
2015/12/17 职场文书
python turtle绘图命令及案例
2021/11/23 Python
Python中Schedule模块使用详解 周期任务神器
2022/04/19 Python