当前位置:天才代写 > tutorial > Python教程 > python多线程编程3: 利用互斥锁同步线程

python多线程编程3: 利用互斥锁同步线程

2017-11-02 08:00 星期四 所属: Python教程 浏览:46

问题的提出

上一节的例子中,每个线程相互独立,彼此之间没有任何关系。此刻假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,按照num举办一些处理惩罚,然后将num加1。很容易写出这样的代码:

# 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

问题发生的原因就是没有节制多个线程对同一资源的会见,对数据造成粉碎,使得线程运行的功效不行预期。这种现象称为“线程不安详”。

互斥锁同步

上面的例子引出了多线程编程的最常见问题:数据共享。当多个线程都修改某一个共享数据的时候,需要举办同步节制。

线程同步可以或许担保多个线程安详会见竞争资源,最简朴的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要变动共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能变动;直到该线程释放资源,将资源的状态酿成“非锁定”,其他的线程才气再次锁定该资源。互斥锁担保了每次只有一个线程举办写入操纵,从而担保了多线程环境下数据的正确性。

threading模块中界说了Lock类,可以利便的处理惩罚锁定:

#建设锁

mutex = threading.Lock()

#锁定

mutex.acquire([timeout])

#释放

mutex.release()

个中,锁定要领acquire可以有一个超时时间的可选参数timeout。假如设定了timeout,则在超时后通过返回值可以判定是否获得了锁,从而可以举办一些其他的处理惩罚。

利用互斥锁实现上面的例子的代码如下:

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

可以看到,插手互斥锁后,运行功效与预期相符。

同步阻塞

当一个线程挪用锁的acquire()要领得到锁时,锁就进入“locked”状态。每次只有一个线程可以得到锁。假如此时另一个线程试图得到这个锁,该线程就会变为“blocked”状态,称为“同步阻塞”(拜见多线程的根基观念)。

直到拥有锁的线程挪用锁的release()要领释放锁之后,锁进入“unlocked”状态。线程调治措施从处于同步阻塞状态的线程中选择一个来得到锁,并使得该线程进入运行(running)状态。

互斥锁最根基的内容就是这些,下一节将接头可重入锁(RLock)和死锁问题。

发送
用户评级
0 (0 票)
评论评分 0 (0 人点评)
 

    关键字:


天才代写-代写联系方式