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的Pyspider为例剖析搜索引擎的网络爬虫实现方法
Mar 30 Python
python实现多线程的两种方式
May 22 Python
python爬取拉勾网职位数据的方法
Jan 24 Python
Php多进程实现代码
May 07 Python
Python2.7环境Flask框架安装简明教程【已测试】
Jul 13 Python
python使用selenium登录QQ邮箱(附带滑动解锁)
Jan 23 Python
pytorch构建多模型实例
Jan 15 Python
python如何保存文本文件
Jun 07 Python
Python Django搭建网站流程图解
Jun 13 Python
python软件都是免费的吗
Jun 18 Python
python 利用toapi库自动生成api
Oct 19 Python
Python中相见恨晚的技巧
Apr 13 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
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
Amazon Prime Video平台《无限住人 -IMMORTAL-》2020年开始TV放送!
2020/03/06 日漫
浅谈Windows下 PHP4.0与oracle 8的连接设置
2006/10/09 PHP
fleaphp rolesNameField bug解决方法
2011/04/23 PHP
常见PHP数据库解决方案分析介绍
2015/09/24 PHP
PHP使用SMTP邮件服务器发送邮件示例
2018/08/28 PHP
JS Timing
2007/04/21 Javascript
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
JavaScript Prototype对象
2009/01/07 Javascript
js 加载并解析XML字符串的代码
2009/12/13 Javascript
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
javascript 子窗体父窗体相互传值方法
2010/05/31 Javascript
javascript针对DOM的应用分析(四)
2012/04/15 Javascript
js判断鼠标同时离开两个div的思路及代码
2013/05/31 Javascript
DOM基础教程之事件对象
2015/01/20 Javascript
JS中JSON对象和String之间的互转及处理技巧
2016/04/06 Javascript
jquery 实现回车登录详解及实例代码
2016/10/23 Javascript
Javascript 普通函数和构造函数的区别
2016/11/05 Javascript
在js中做数字字符串补0(js补零)
2017/03/25 Javascript
ES6新特性之Object的变化分析
2017/03/31 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
使用3D引擎threeJS实现星空粒子移动效果
2020/09/13 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
vue-cli监听组件加载完成的方法
2018/09/07 Javascript
Openlayers显示地理位置坐标的方法
2020/09/28 Javascript
[04:00]黄浦江畔,再会英雄——完美世界DOTA2 TI9应援视频
2019/07/31 DOTA
Django处理文件上传File Uploads的实例
2018/05/28 Python
PyQt5实现简易电子词典
2019/06/25 Python
英国厨房与餐具用品为主的设计品牌:Joseph Joseph
2018/04/26 全球购物
技校生自我鉴定范文
2013/09/26 职场文书
毕业生个人的自我评价优秀范文
2013/10/03 职场文书
行政人事岗位职责
2014/03/17 职场文书
毕业生就业推荐表自我鉴定
2014/03/20 职场文书
入党积极分子半年考察意见
2015/06/02 职场文书
Vue.js中v-bind指令的用法介绍
2022/03/13 Vue.js
ssh服务器拒绝了密码 请再试一次已解决(亲测有效)
2022/08/14 Servers