博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Python线程同步机制

Posted on 2017-07-26 14:50  bw_0927  阅读(247)  评论(0)    收藏  举报

https://harveyqing.gitbooks.io/python-read-and-write/content/python_advance/python_thread_sync.html

 

锁通常被用来实现对共享资源的同步访问。为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁:

lock = Lock()

lock.acquire()  #: will block if lock is already held
... access shared resource
lock.release()

注意,即使在访问共享资源的过程中出错了也应该释放锁,可以用try-finally来达到这一目的:

lock.acquire()
try:
    ... access shared resource
finally:
    lock.release()  #: release lock, no matter what

在Python 2.5及以后的版本中,你可以使用with语句。在使用锁的时候,with语句会在进入语句块之前自动的获取到该锁对象,然后在语句块执行完成后自动释放掉锁:

from __future__ import with_statement  #: 2.5 only

with lock:
    ... access shared resource

acquire方法带一个可选的等待标识,它可用于设定当有其它线程占有锁时是否阻塞。如果你将其值设为False,那么acquire方法将不再阻塞,只是如果该锁被占有时它会返回False:

if not lock.acquire(False):
    ... 锁资源失败
else:
    try:
        ... access shared resource
    finally:
        lock.release()

你可以使用locked方法来检查一个锁对象是否已被获取,注意不能用该方法来判断调用acquire方法时是否会阻塞,因为在locked方法调用完成到下一条语句(比如acquire)执行之间该锁有可能被其它线程占有。

if not lock.locked():
    #: 其它线程可能在下一条语句执行之前占有了该锁
    lock.acquire()  #: 可能会阻塞

Re-Entrant Locks (RLock)

Semaphores

Conditions

 
http://www.cnblogs.com/holbrook/archive/2012/03/04/2378947.html


# encoding: UTF-8
import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num
        time.sleep(1)
        num = num+1
        msg = self.name+' set num to '+str(num)
        print msg
num = 0
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

但是运行结果是不正确的:

Thread-5 set num to 2
Thread-3 set num to 3
Thread-2 set num to 5
Thread-1 set num to 5
Thread-4 set num to 4

 

#创建锁
mutex = threading.Lock()
#锁定
mutex.acquire([timeout])
#释放
mutex.release()


import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire(1):  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

运行结果:

Thread-3 set num to 1
Thread-4 set num to 2
Thread-5 set num to 3
Thread-2 set num to 4
Thread-1 set num to 5

可以看到,加入互斥锁后,运行结果与预期相符。

http://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p04_locking_critical_sections.html