Python@Thread锁示例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python@Thread锁示例相关的知识,希望对你有一定的参考价值。

  当出现竞态条件时候,即在同一个时刻只有一个线程可以进入临界区,需要使用同步。

常见的同步原语有两种:锁/互斥,信号量。

  锁是最简单,最低级的机制。

首先看一个不使用锁时候的多线程示例:

from atexit import register
from time import sleep, ctime
from threading import currentThread, Thread
from random import randrange


class cleanOutput(list):
    def __str__(self):
        return ,.join(self)

loops = [randrange(2, 5) for x in range(randrange(3, 7))]
remaining = cleanOutput()


def loop(nsec):
    myname = currentThread().name
    remaining.append(myname)
    print({0} starting at {1}.format(myname, ctime()))
    sleep(nsec)
    remaining.remove(myname)
    print({0} end at {1}.format(myname, ctime()))
    print(remaining {0}.format(remaining))


def main():
    for i in loops:
        Thread(target=loop, args=(i,)).start()


@register
def _atexit():
    print("end!")


if __name__ == __main__:
    main()

输出结果1:

Thread-1 starting at Tue Dec 20 23:12:03 2016
Thread-2 starting at Tue Dec 20 23:12:03 2016
Thread-3 starting at Tue Dec 20 23:12:03 2016
Thread-4 starting at Tue Dec 20 23:12:03 2016
Thread-5 starting at Tue Dec 20 23:12:03 2016
Thread-6 starting at Tue Dec 20 23:12:03 2016
Thread-2 end at Tue Dec 20 23:12:05 2016
Thread-3 end at Tue Dec 20 23:12:05 2016
Thread-5 end at Tue Dec 20 23:12:05 2016
remaining Thread-1,Thread-4,Thread-6
remaining Thread-1,Thread-4,Thread-6
remaining Thread-1,Thread-4,Thread-6
Thread-1 end at Tue Dec 20 23:12:06 2016
remaining Thread-4,Thread-6
Thread-6 end at Tue Dec 20 23:12:06 2016
remaining Thread-4
Thread-4 end at Tue Dec 20 23:12:06 2016
remaining
end!

输出结果2:

Thread-1 starting at Tue Dec 20 23:18:45 2016
Thread-2 starting at Tue Dec 20 23:18:45 2016
Thread-3 starting at Tue Dec 20 23:18:45 2016
Thread-4 starting at Tue Dec 20 23:18:45 2016
Thread-1 end at Tue Dec 20 23:18:47 2016
remaining Thread-2,Thread-3,Thread-4
Thread-3 end at Tue Dec 20 23:18:47 2016
Thread-2 end at Tue Dec 20 23:18:47 2016
remaining Thread-4
remaining Thread-4
Thread-4 end at Tue Dec 20 23:18:48 2016
remaining
end!

可以看到输出的结果非常奇怪,当多个线程同时使用remaining列表时候,结果会出现意外。

当使用锁时,即

 1 from atexit import register
 2 from time import sleep, ctime
 3 from threading import currentThread, Thread, Lock
 4 from random import randrange
 5 
 6 
 7 class cleanOutput(list):
 8     def __str__(self):
 9         return ,.join(self)
10 
11 loops = [randrange(2, 5) for x in range(randrange(3, 7))]
12 remaining = cleanOutput()
13 lock = Lock()
14 
15 
16 def loop(nsec):
17     myname = currentThread().name
18     with lock:          #也可以使用lock.acquire()和lock.release()
19         remaining.append(myname)          
20         print({0} starting at {1}.format(myname, ctime()))
21     sleep(nsec)
22     with lock:
23         remaining.remove(myname)
24         print({0} end at {1}.format(myname, ctime()))
25         print(remaining {0}.format(remaining))
26 
27 
28 def main():
29     for i in loops:
30         Thread(target=loop, args=(i,)).start()
31 
32 
33 @register
34 def _atexit():
35     print("end!")
36 
37 
38 if __name__ == __main__:
39     main()

输出结果为:

Thread-1 starting at Tue Dec 20 23:22:53 2016
Thread-2 starting at Tue Dec 20 23:22:53 2016
Thread-3 starting at Tue Dec 20 23:22:53 2016
Thread-4 starting at Tue Dec 20 23:22:53 2016
Thread-5 starting at Tue Dec 20 23:22:53 2016
Thread-6 starting at Tue Dec 20 23:22:53 2016
Thread-1 end at Tue Dec 20 23:22:55 2016
remaining Thread-2,Thread-3,Thread-4,Thread-5,Thread-6
Thread-4 end at Tue Dec 20 23:22:55 2016
remaining Thread-2,Thread-3,Thread-5,Thread-6
Thread-2 end at Tue Dec 20 23:22:55 2016
remaining Thread-3,Thread-5,Thread-6
Thread-5 end at Tue Dec 20 23:22:56 2016
remaining Thread-3,Thread-6
Thread-6 end at Tue Dec 20 23:22:57 2016
remaining Thread-3
Thread-3 end at Tue Dec 20 23:22:57 2016
remaining
end!

结果正常了

 

参考资料:Python核心编程.第四章.Wesley Chun著

















































以上是关于Python@Thread锁示例的主要内容,如果未能解决你的问题,请参考以下文章

LockSupport.java 中的 FIFO 互斥代码片段

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

python ---thread

需要示例代码片段帮助

处理屏幕旋转上的片段重复(带有示例代码)

为啥基于锁的程序不能组成正确的线程安全片段?