标签:同步原语 __str__ append exit read start style rand name
当出现竞态条件时候,即在同一个时刻只有一个线程可以进入临界区,需要使用同步。
常见的同步原语有两种:锁/互斥,信号量。
锁是最简单,最低级的机制。
首先看一个不使用锁时候的多线程示例:
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著
标签:同步原语 __str__ append exit read start style rand name
原文地址:http://www.cnblogs.com/fcyworld/p/6205003.html