import time
import threading lock = threading.RLock() n = 10 def task(arg):
# 加锁,此区域的代码同一时刻只能有一个线程执行
lock.acquire() # 获取当前线程对象
thread_obj = threading.current_thread()
# 获取当前线程名字
name = thread_obj.getName() global n
n = arg
time.sleep(1)
print('当前线程', name, '修改后n的值为:', n) # 释放锁
lock.release() for i in range(5):
t = threading.Thread(target=task, args=(i,))
t.setName(str(i))
t.start()

'''

期望结果-->加锁情况:

当前线程 0 修改后n的值为: 0

当前线程 1 修改后n的值为: 1

当前线程 2 修改后n的值为: 2

当前线程 3 修改后n的值为: 3

当前线程 4 修改后n的值为: 4

'''

'''

不期望结果-->没加锁情况

当前线程 0 修改后n的值为: 4

当前线程 1 修改后n的值为: 4

当前线程 2 修改后n的值为: 4

当前线程 3 修改后n的值为: 4

当前线程 4 修改后n的值为: 4

'''

引子:为什么要加锁?

需求:每个线程将一个数字添加到列表,然后取出自己放的数字,线程结束.

希望得到的结果如下:

'''

0 0

1 1

2 2

3 3

4 4

'''

代码:

import threading

import time

lst = []

def func(arg):

# 线程安全

lst.append(arg)

time.sleep(0.1)

m = lst[-1]

print(arg,m)

for i in range(5):

t = threading.Thread(target=func,args=(i,))

t.start()

总结:

从上面这个例子看,如果不加锁,每个线程放进去自己的数字,再取最后一个数字,就不一定是自己放的,因为这个时间,可能其他线程也放进去了,你拿到的,可能是其他线程放的.所以这个时候就需要加锁,限制一个线程没操作完,另一个绝对不能动.

1.锁:Lock(1次放1个)

import threading

import time

lst = []

lock = threading.Lock()

def func(arg):

lock.acquire()

lst.append(arg)

time.sleep(0.1)

m = lst[-1]

lock.release()

for i in range(5):

t = threading.Thread(target=func,args=(i,))

t.start()

2.锁:RLock(1次放1个)

import threading
import time lst = []
lock = threading.RLock() def func(arg):
lock.acquire()
lock.acquire()
lst.append(arg)
time.sleep(0.1)
m = lst[-1]
print(arg, m)
lock.release()
lock.release() for i in range(5):
t = threading.Thread(target=func, args=(i,))
t.start()

PS:Lock和RLock的区别是RLock可以多次加锁.

3.锁:BoundedSemaphore(1次放N个)信号量

import time
import threading lst = []
# 一次放3个
lock = threading.BoundedSemaphore(3) def func(arg):
lock.acquire()
lst.append(arg)
m = lst[-1]
print(arg, m)
time.sleep(3)
lock.release() for i in range(10):
t = threading.Thread(target=func, args=(i,))
t.start()

4.锁:Condition(1次放x个)

方法1:

import time
import threading lst = []
lock = threading.Condition() def func(arg):
print('start...')
lock.acquire()
lock.wait()
lst.append(arg)
m = lst[-1]
print(arg, m)
time.sleep(1)
lock.release() for i in range(10):
t = threading.Thread(target=func, args=(i,))
t.start() while True:
num = int(input('>>>:'))
lock.acquire()
# 控制放几个线程执行,比如写3个,但是线程实际2个,那就是2个了
lock.notify(num) # 3
lock.release()

方法2:

import time
import threading lock = threading.Condition() def func1():
print('start...')
input('>>>:')
return True def func2(arg):
print('\n线程进来了')
# func1作为执行条件
lock.wait_for(func1)
print(arg)
time.sleep(1) for i in range(10):
t = threading.Thread(target=func2, args=(i,))
t.start()

5.锁:Event(1次放所有)

import threading

lock = threading.Event()

def func(arg):
print('线程来了')
# 加锁:红灯
lock.wait()
print(arg) for i in range(10):
t = threading.Thread(target=func, args=(i,))
t.start()
input('>>>:')
lock.set() # 绿灯
lock.clear() # 再次变红灯 for i in range(10):
t = threading.Thread(target=func, args=(i,))
t.start()
input('>>>')
lock.set()

总结:

线程安全,列表和字典线程安全;

为什么要加锁?

- 非线程安全

- 控制一段代码

python多线程锁lock/Rlock/BoundedSemaphore/Condition/Event的更多相关文章

  1. python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 mutex = threading.Lock() #锁 ...

  2. Python多线程锁

    [Python之旅]第六篇(四):Python多线程锁   python lock 多线程 多线程使用方法 多线程锁 摘要:   在多线程程序执行过程中,为什么需要给一些线程加锁以及如何加锁,下面就来 ...

  3. 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition

    我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...

  4. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  5. Python3学习之路~9.3 GIL、线程锁之Lock\Rlock\信号量、Event

    一 Python GIL(Global Interpreter Lock) 全局解释器锁 如果一个主机是单核,此时同时启动10个线程,由于CPU执行了上下文的切换,让我们宏观上看上去它们是并行的,但实 ...

  6. [b0039] python 归纳 (二四)_多进程数据共享和同步_锁Lock&RLock

    # -*- coding: utf-8 -*- """ 多进程 锁使用 逻辑: 10个进程各种睡眠2秒,然后打印. 不加锁同时打印出来,总共2秒,加锁一个接一个打印,总共 ...

  7. python 多进程锁Lock和共享内存

    多进程锁 lock = multiprocessing.Lock() 创建一个锁 lock.acquire() 获取锁 lock.release() 释放锁 with lock: 自动获取.释放锁 类 ...

  8. 线程使用方法 锁(lock,Rlock),信号了(Semaphore),事件(Event),条件(Ccndition),定时器(timer)

    2线程的使用方法  (1)锁机制       递归锁           RLock()    可以有无止尽的锁,但是会有一把万能钥匙       互斥锁:           Lock()     ...

  9. python 多线程锁机制

    GIL(全局解释器锁) GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念,是为了实现不同线程对共享资源访问的互斥,才引入了GIL 在Cpython解释器 ...

随机推荐

  1. QT界面 使用QStyledItemDelegate QPainter QStyleOptionViewItem QModelIndex组合实现项的绘制

    QStyledItemDelegate类为来自模型的数据项提供了显示和编辑工具. 当在Qt项视图(例如QTableView)中显示来自模型的数据时,各个项由委托(delegate)绘制.此外,当编辑一 ...

  2. CCNA2.0笔记_OSPF v2

    OSPF(开放最短路径优先)协议概述: - 链路状态路由协议 - 无类路由协议 - 要点:RouterID.区域ID - 触发更新 .以传播 LSA 代替路由表更新 - 快速响应变更(比距离矢量路由协 ...

  3. ORACLE修改列名与列类型

    --修改列名 alter table 表名 rename column 旧列名 to 新列名; --修改列类型 )); 删除表的一列: alter table 表名 drop column 列名 给表 ...

  4. Unix系统编程()lseek系统调用

    之前知道lseek这个系统调用可以改变文件的偏移量,或者叫偏移量或指针. 文件偏移量是指执行下一个read或者write操作的文件起始位置,会以相对于文件头部起始点的文件当前位置来表示. 除非指定了O ...

  5. [转]所有编程皆为 Web 编程

    Web编程还远远没有达到完美的境地.其实,还有点乱!没错,随便会写点代码的人就能三下两下地搞出一个糟糕的Web应用:也确实,99%的Web 应用都似狗屎一堆.但是,这也意味着,相当“聪明”的程序员们正 ...

  6. android最佳实践的建议(翻译自android-best-practices)

    Best practices in Android development Use Gradle and its recommended project structure 使用Gradle和其推荐的 ...

  7. Tutorial : How to Create a Border Glow Effect in JavaFX

    http://blog.idrsolutions.com/2014/02/tutorial-create-border-glow-effect-javafx/ ———————————————————— ...

  8. 第二百一十四节,jQuery EasyUI,Calendar(日历)组件

    jQuery EasyUI,Calendar(日历)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Canlendar(日历)组件的使用方法 ...

  9. 第一百六十节,封装库--JavaScript,ajax注册表单到数据库

    封装库--JavaScript,ajax注册表单到数据库 效果图 前台js var biaodan = $().xu_lie_biao_dan($('form').sh_jd()); //序列化获取表 ...

  10. SpringMVC整合Shiro(配解释)

    第一步:配置web.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --> ...