再谈Python多线程--threading各类锁
来源:互联网 发布:什么是js面向对象编程 编辑:程序博客网 时间:2024/06/08 15:02
使用多线程的好处是提高执行效率,但同时带来了数据同步的问题。即多个线程同时对一个对象进行操作时,可能会出现资源冲突的问题;在不加锁的情况下,代码可能并未像我们想向的那样工作。举个栗子:
为了保证多线程对共享资源的访问顺序,一般会引入锁机制。有了锁的加入,当子线程在操作共享资源时会先对其进行锁定,之后再进行操作;而此时其它的线程是不能对该共享资源进行操作的。这样就保证了同一个时间只有一个线程在操作共享资源。在Python中多线程锁有几种实现形式:
首先,Lock是我们最常用的锁,它主要提供2个操作方法:acquire【申请锁】、release【释放锁】。
RLock是Recursion Lock的简称,即递归锁。它主要用于递归操作中,比如:递归函数。它与Lock的区别在于RLock在同一个线程内可以重复申请,所以它可以被用于递归操作中。
Condition是一把有条件的锁。本质上它是对Lock/RLock等基本锁对象的封装,在实例Condition对象时需要传入需要的基本锁。而在使用上Condition除了可以使用acquire和release方法,还有wait、notify、notifyAll等方法。
import threadingn = 2max_n = 10000x = 0def countup(n): global x for i in range(n): x += 1 print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n): t = threading.Thread(target=countup, args=(max_n,)) t.start()执行结果:
Thread-1: 1Thread-2: 2...Thread-2: 19912按照期望最后应该打印到20000才结束,而实际上只打印了19912次,并且每次执行的结果很可能是不一样的。
为了保证多线程对共享资源的访问顺序,一般会引入锁机制。有了锁的加入,当子线程在操作共享资源时会先对其进行锁定,之后再进行操作;而此时其它的线程是不能对该共享资源进行操作的。这样就保证了同一个时间只有一个线程在操作共享资源。在Python中多线程锁有几种实现形式:
- threading.Lock
- threading.RLock
- threading.Condition
- threading.Semaphore
- threading.Event
- threading.Timer
- threading.Barrier
首先,Lock是我们最常用的锁,它主要提供2个操作方法:acquire【申请锁】、release【释放锁】。
import threadingn = 2max_n = 10000x = 0lock = threading.Lock()def countup(n): global x for i in range(n): lock.acquire() x += 1 lock.release() print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n): t = threading.Thread(target=countup, args=(max_n,)) t.start()这次在加了锁之后,程序终于可以正常工作了。因为我们在对x变量进行操作的前进行了加锁操作,保证了对x的修改操作是一个原子操作(不可被分割的操作)。
RLock是Recursion Lock的简称,即递归锁。它主要用于递归操作中,比如:递归函数。它与Lock的区别在于RLock在同一个线程内可以重复申请,所以它可以被用于递归操作中。
import threadingn = 2max_n = 10x = 0lock = threading.RLock()def countup(m): global x if m > 0: lock.acquire() x += 1 countup(m - 1) lock.release() print '%s: %s\r\n' % (threading.currentThread().getName(), x) else: returnfor i in range(n): t = threading.Thread(target=countup, args=(max_n,)) t.start()上面我们使用递归替代了for循环,并且递归调用是在获取到锁的过程中。如果你把上面的RLock替换成Lock,那么它将会被自己组塞住。当然你也可以使用尾递归的写法,那样还是可以使用Lock模块;这里只是说明RLock的应用场景。
Condition是一把有条件的锁。本质上它是对Lock/RLock等基本锁对象的封装,在实例Condition对象时需要传入需要的基本锁。而在使用上Condition除了可以使用acquire和release方法,还有wait、notify、notifyAll等方法。
阅读全文
0 0
- 再谈Python多线程--threading各类锁
- python多线程threading.Lock锁实例
- python多线程threading及锁机制
- Python 多线程 Threading模块
- Python threading多线程编程
- python --- 多线程之threading
- Python多线程1:threading
- python 多线程threading
- python threading多线程模块
- python多线程threading
- python 多线程(threading)
- python多线程-threading模块
- Python多线程-threading
- 32 Python 多线程 - threading
- Python threading 多线程
- python--threading多线程总结
- Python多线程threading用法
- python中的多线程-threading
- 3-3 构造函数的调用(高级)
- 【整理】unity3d优化总结篇
- 1143 面向对象程序设计上机练习四(变量引用)
- 数据结构(1)-选择排序和插入排序
- 【转载】[一文一命令]awk命令详解
- 再谈Python多线程--threading各类锁
- linux下tomcat重新启动
- hdu5968-重要的细节&记忆化&坑-异或密码
- 在eclipse程序中设置的断点上有一个斜杠无法进行debug调试
- RocketMQ源码解析-Broker的HA实现
- c语言作业(一)
- java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 520536 bytes
- 【Vue】3.vue2.0嵌套路由-params传递参数
- Android帧、补间、属性动画