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 相关文章推荐
pyqt4教程之实现半透明的天气预报界面示例
Mar 02 Python
python实现telnet客户端的方法
Apr 15 Python
Python之pandas读写文件乱码的解决方法
Apr 20 Python
在Python中增加和插入元素的示例
Nov 01 Python
python实现微信定时每天和女友发送消息
Apr 29 Python
Pandas之MultiIndex对象的示例详解
Jun 25 Python
Python迭代器iterator生成器generator使用解析
Oct 24 Python
python zip()函数使用方法解析
Oct 31 Python
Python matplotlib实时画图案例
Apr 23 Python
Scrapy爬虫文件批量运行的实现
Sep 30 Python
用Python自动清理系统垃圾的实现
Jan 18 Python
Python数据类型最全知识总结
May 31 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
在JavaScript中调用php程序
2009/03/09 PHP
php+ajax制作无刷新留言板
2015/10/27 PHP
php实现的http请求封装示例
2016/11/08 PHP
lyhucSelect基于Jquery的Select数据联动插件
2011/03/29 Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
2013/12/02 Javascript
JavaScript将页面表格导出为Excel的具体实现
2013/12/27 Javascript
简介JavaScript中的italics()方法的使用
2015/06/08 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
浅析Javascript匿名函数与自执行函数
2016/02/06 Javascript
基于javascript html5实现3D翻书特效
2016/03/14 Javascript
JS实现图片高斯模糊切换效果的焦点图实例
2017/01/21 Javascript
js实现带简单弹性运动的导航条
2017/02/22 Javascript
js实现本地图片文件拖拽效果
2017/07/18 Javascript
浅谈在vue项目中如何定义全局变量和全局函数
2017/10/24 Javascript
Node.js创建Web、TCP服务器
2017/12/05 Javascript
jQuery实现的回车触发按钮事件功能示例
2018/03/25 jQuery
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
vue组件挂载到全局方法的示例代码
2018/08/02 Javascript
工作中常用到的ES6语法
2018/09/04 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
vue 实现滚动到底部翻页效果(pc端)
2019/07/31 Javascript
JavaScript获取页面元素的常用方法详解
2019/09/28 Javascript
JS代码检查工具ESLint介绍与使用方法
2020/02/04 Javascript
基于JavaScript实现大文件上传后端代码实例
2020/08/18 Javascript
JS pushlet XMLAdapter适配器用法案例解析
2020/10/16 Javascript
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python 抓取动态网页内容方案详解
2014/12/25 Python
python paramiko远程服务器终端操作过程解析
2019/12/14 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
2020/06/02 Python
香港优质食材和美酒专门店:FoodWise
2017/09/01 全球购物
捷克玩具商店:Bambule
2019/02/23 全球购物
竞选班干部演讲稿400字
2014/08/20 职场文书
元旦标语大全
2014/10/09 职场文书
预备党员群众意见
2015/06/01 职场文书
2015选调生工作总结
2015/07/24 职场文书
会计实训总结范文
2015/08/03 职场文书