python多线程编程(二)--threading模块

threading模块对象

对象

描述

Thread

一个线程的执行对象

Lock

锁对象

RLock

可重入锁对象,使单线程可以再次获得已经获得了的锁(递归锁定)

Condition

条件变量,让一个线程停下来,等待其它线程满足了某个条件

Event

事件对象,通用的条件变量

Semaphore

信号量

BoundedSemaphore

Semaphore类似,只是它不允许超过初始值

Timer

Thread相似,不过它要等待一段时间才开始运行

threadingThread类是最主要的运行对象。

Thread对象的函数

函数

描述

start()

线程开始执行

run()

线程功能函数

join(timeout=None)

程序挂起,直到线程结束;如果给了timeout,则最多阻塞timeout

getName()

返回线程名字

setName(name)

设置线程名字

isAlive()

这个线程是否还在执行

isDaemon()

返回线程的daemon标志

setDaemon(daemonic)

设置线程的daemon属性,一定要在调用start()函数前调用

使用Thread类,我们介绍三种方法来创建线程。

●       创建一个Thread的实例,传给它一个函数

●       创建一个Thread的实例,传给它一个可调用的类对象

●       Thread派生出一个子类,创建一个这个子类的实例

下面看第一种,创建一个Thread的实例,传给它一个函数

我们将初始化一个Thread对象,把函数(及其参数)传进去。这种方式实例化一个Thread与调用thread.start_new_thread()之间的最大区别就是,新线程不会立即开始。当你创建线程对象又不想立即开始执行的时候,这是很有用的。

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #coding: utf-8  
  2. import threading  
  3. from time import sleep, ctime  
  4.   
  5. loops = [4,2]  
  6.   
  7. def  loop(nloop, nsec):  
  8.     print 'loop', nloop, 'start at:', ctime()  
  9.     print 'loop %d 挂起%d秒' % (nloop, nsec)  
  10.     sleep(nsec)  
  11.     print 'loop', nloop, 'done at:', ctime()  
  12.   
  13. def main():  
  14.     print 'main thread start!'  
  15.     threads = []  #线程列表  
  16.     nloops = range(len(loops))  
  17.   
  18.     for i in nloops:  
  19.         t = threading.Thread(target=loop, args=(i, loops[i]))  
  20.         threads.append(t)  
  21.   
  22.     for i in nloops:  
  23.         threads[i].start()  
  24.   
  25.     for i in nloops:  
  26.         threads[i].join()  #等待线程结束  
  27.   
  28.     print 'all done at:', ctime()  
  29.   
  30. if __name__ == '__main__':  
  31.     main()  

运行结果:


这种方式就省了管理一堆锁的功夫了,只要对每个线程调用join()函数,就会等到线程结束。

另外,如果你的主线程除了等线程结束外,还有其它的事情要做(如处理或等待其它的客户请求),那就不用调用join()。一旦线程启动后,就会一直运行,直到线程的函数结束,退出为止。所以只有在你要等待线程结束的时候才要调用join()

第二种方式,创建一个Thread的实例,传给它一个可调用的类对象

这种方式就是在第一种方式的情况下,将函数封装进类对象里面,由类对象提供功能函数。在创建Thread对象时会实例化这个类对象。

[python]  view plain copy
  1. #coding: utf-8  
  2. import threading  
  3. from time import sleep, ctime  
  4.   
  5. loops = [4,2]  
  6.   
  7. class Func(object):  
  8.     def __init__(self, func, args, name=""):  
  9.         self.name = name  
  10.         self.func = func  
  11.         self.args =args  
  12.   
  13.     def __call__(self):  
  14.         self.res = self.func(*self.args)  #如果python版本是1.6以下,就使用apply(self.func, self.args)  
  15.   
  16. def  loop(nloop, nsec):  
  17.     print 'loop', nloop, 'start at:', ctime()  
  18.     print 'loop %d 挂起%d秒' % (nloop, nsec)  
  19.     sleep(nsec)  
  20.     print 'loop', nloop, 'done at:', ctime()  
  21.   
  22. def main():  
  23.     print 'main thread start!'  
  24.     threads = []  #线程列表  
  25.     nloops = range(len(loops))  
  26.   
  27.     for i in nloops:  
  28.         t = threading.Thread(target=Func(loop, (i, loops[i]), loop.__name__))  
  29.         threads.append(t)  
  30.   
  31.     for i in nloops:  
  32.         threads[i].start()  
  33.   
  34.     for i in nloops:  
  35.         threads[i].join()  #等待线程结束  
  36.   
  37.     print 'all done at:', ctime()  
  38.   
  39. if __name__ == '__main__':  
  40.     main()  

创建新线程的时候,Thread对象会调用我们的Func对象,这时会用到一个特殊函数__call__()这是python的一个特性,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。比如实现了__call__函数的Func对象实例instance,形如instance(arg1,arg2,...)实际上调用的就是instance.__call__(arg1,arg2,...)

第三种方式,Thread派生出一个子类,创建这个子类的实例

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #coding: utf-8  
  2. import threading  
  3. from time import sleep, ctime  
  4.   
  5. loops = [4,2]  
  6.   
  7. class MyThread(threading.Thread):  
  8.     def __init__(self, func, args, name=""):  
  9.         threading.Thread.__init__(self)  
  10.         self.name = name  
  11.         self.func = func  
  12.         self.args =args  
  13.   
  14.     def run(self):  
  15.         self.res = self.func(*self.args)  
  16.           
  17. def  loop(nloop, nsec):  
  18.     print 'loop', nloop, 'start at:', ctime()  
  19.     print 'loop %d 挂起%d秒' % (nloop, nsec)  
  20.     sleep(nsec)  
  21.     print 'loop', nloop, 'done at:', ctime()  
  22.   
  23. def main():  
  24.     print 'main thread start!'  
  25.     threads = []  
  26.     nloops = range(len(loops))  
  27.   
  28.     for i in nloops:  
  29.         t = MyThread(loop, (i, loops[i]), loop.__name__)  
  30.         threads.append(t)  
  31.   
  32.     for i in nloops:  
  33.         threads[i].start()  
  34.   
  35.     for i in nloops:  
  36.         threads[i].join()  
  37.   
  38.     print 'all done at:', ctime()  
  39.   
  40. if __name__ == '__main__':  
  41.     main()  

这种方式使创建线程对象的代码更简洁。

原文:http://blog.csdn.net/whoami021/article/details/21265263

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值