*注:在实际使用过程当中不建议使用 thread 进行多线程编程,本文档只为学习(或熟悉)多线程使用。编程
Thread 模块除了派生线程外,还提供了基本的同步数据结构,称为锁对象(lock object,也叫原语锁、互斥锁、互斥和二进制信号量)。数据结构
经常使用线程函数以及 LockType 锁对象的方法:多线程
函数/方法 | 描述 |
---|---|
thread 模块的函数 | |
start_new_thread(function, args, kwargs=None) | 派生一个新的线程,使用给定的 args 和可选的 kwargs 来执行 function |
allocate_lock() | 分配 LockType 锁对象 |
exit() | 给线程退出指令 |
LockType 锁对象方法 | |
acquire(wait=None) | 尝试获取锁对象 |
locked() | 若是获取了锁对象则返回True,不然返回 Flase |
release() | 释放锁 |
使用 thread 模块的简单例子,代码以下(mtsleepA.py):app
1 import thread 2 from time import sleep, ctime 3 4 def loop0(): 5 print 'start loop 0 at:', ctime() 6 sleep(4) 7 print 'loop 0 Done at:', ctime() 8 9 def loop1(): 10 print 'start loop 1 at:', ctime() 11 sleep(2) 12 print 'loop 1 Done at:', ctime() 13 14 def main(): 15 print 'starting at:', ctime() 16 thread.start_new_thread(loop0, ()) 17 thread.start_new_thread(loop1, ()) 18 sleep(6) 19 print 'all DONE at:', ctime() 20 21 if __name__ == '__main__': 22 main()
输出结果:函数
1 starting at: Sun Jul 22 21:38:00 2018 2 start loop 0 at: Sun Jul 22 21:38:00 2018 3 start loop 1 at: Sun Jul 22 21:38:00 2018 4 loop 1 Done at: Sun Jul 22 21:38:02 2018 5 loop 0 Done at: Sun Jul 22 21:38:04 2018 6 all DONE at: Sun Jul 22 21:38:06 2018
在这个脚本的代码中,增长了一个 sleep(6) 调用,为何要这么作呢?这是由于若是咱们没有阻止主线程继续执行,它将会继续执行下一条语句,显示“all done”而后退出,而 loop0() 和 loop1() 这两个线程将直接终止。oop
使用线程和锁的简单例子,代码以下(mtsleepB.py):学习
1 import thread 2 from time import sleep, ctime 3 4 loops = [4,2] 5 6 def loop(nloop, nsec, lock): 7 print 'start loop', nloop, 'at:', ctime() 8 sleep(nsec) 9 print 'loop', nloop, 'done at:', ctime() 10 lock.release() # 释放锁 11 12 def main(): 13 print 'starting at:', ctime() 14 locks = [] 15 nloops = range(len(loops)) 16 17 for i in nloops: 18 lock = thread.allocate_lock() # 分配 LockType 对象 19 lock.acquire() # 尝试获取锁对象 20 locks.append(lock) 21 22 for i in nloops: 23 thread.start_new_thread(loop, (i, loops[i], locks[i])) # 派生新线程 24 25 for i in nloops: 26 # 等待全部锁释放后退出循环继续后面操做 27 while locks[i].locked(): # 当获取了锁的时候为 True,全部的锁都释放后为 Flase 28 pass 29 30 print 'all DONE at:', ctime() 31 32 if __name__ == '__main__': 33 main()
输出结果为:
1 starting at: Sun Jul 22 22:25:45 2018 2 start loop 1 at:start loop Sun Jul 22 22:25:45 2018 3 0 at: Sun Jul 22 22:25:45 2018 4 loop 1 done at: Sun Jul 22 22:25:47 2018 5 loop 0 done at: Sun Jul 22 22:25:49 2018 6 all DONE at: Sun Jul 22 22:25:49 2018
main() 函数中锁相关的主要流程(第一个 for 循环)解释:ui
首先建立一个锁列表,经过使用 thread.allocate_lock() 函数获得锁对象;spa
再经过 acquire() 方法取得每一个锁(取得锁的效果至关于“把锁锁上”);线程
把锁锁上后将它添加到锁列表 locks 中;
为何不在上锁的循环中启动线程呢?
第一,想要同步线程,让全部的线程最后同时都完成;