python提供两个模块支持多线程编程:thread和threading。
thread模块函数
函数 |
描述 |
start_new_thread(function,args,kwargs=None) |
产生一个新线程,在新线程中用指定参数和可选的kwargs调用function函数 |
allocate_lock() |
分配一个LockType类型的锁对象(注意,此时还没有获得锁) |
exit() |
退出线程 |
LockType类型锁对象的函数
acquire(wait=None) |
尝试获取锁对象 |
locked() |
如果获得了锁对象返回True,否则返回False |
release() |
释放锁 |
接下来使用thread模块编写多线程。
#coding: utf-8 import thread from time import sleep, ctime def loop0(): print ‘loop0 start at:‘, ctime() print ‘loop0挂起4秒‘ sleep(4) print ‘loop0 done at:‘, ctime() def loop1(): print ‘loop1 start at:‘, ctime() print ‘loop1挂起2秒‘ sleep(2) print ‘loop1 done at:‘, ctime() def main(): print ‘main thread start!‘ thread.start_new_thread(loop0, ()) thread.start_new_thread(loop1, ()) sleep(6) #主线程睡眠等待子线程结束 print ‘all done at:‘, ctime() if __name__ == ‘__main__‘: main()
运行结果:
下面代码的运行结果都是这样,就不给出了。
相信大家都看到注释,这种方法的缺点就在主线程要睡眠一段时间等待子线程全部结束,不然如果结束主线程,那么子线程都会结束。但是子线程会运行多长时间一般是很难确定的。
下面我们看第二种方法。
既然不知道子线程的执行时间,那么我们换一种方式,我们采用锁的方式来控制主线程退出。
用锁怎么实现多线程呢?对于每一个子线程,我们都给它加锁,在执行结束后再释放锁,这样主线程的工作就是检查没一个子线程的加锁状态,如果都已经释放锁了,那就表示子线程全部执行结束,就可以退出了。
看具体实现代码:
#coding: utf-8 import thread from time import sleep, ctime loops = [4,2] def loop(nloop, nsec, lock): print ‘loop‘, nloop, ‘start at:‘, ctime() print ‘loop %d 挂起%d秒‘ % (nloop, nsec) sleep(nsec) print ‘loop‘, nloop, ‘done at:‘, ctime() lock.release() def main(): print ‘main thread start!‘ locks = [] #锁列表 nloops = range(len(loops)) for i in nloops: lock = thread.allocate_lock() lock.acquire() locks.append(lock) for i in nloops: thread.start_new_thread(loop, (i, loops[i], locks[i])) for i in nloops: while locks[i].locked(): pass #主线程检查每一个子线程的加锁状态 print ‘all done at:‘, ctime() if __name__ == ‘__main__‘: main()
实际上,我们不建议使用thread模块。首先,更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突。其次,低级别的thread模块的同步原语只有一个,而threading模块则有很多。
还有一个原因是,使用thread对于你的进程什么时候应该结束完全没有控制,当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作。但是threading模块能确保重要的子线程退出后进程才退出。
不过如果想访问线程的底层结构,那就可能要使用thread模块了。
我们将在下一篇文章给出threading模块的使用。