一个基于threading模块的多线程脚本

threading模块比thread模块更加高级,不仅提供了Thread类还提供了各种非常好的同步机制。以下的例子实现的功能与上一个thread多线程的脚本功能一样(两个线程同时运行,一个运行3s,一个运行5s,验证总的运行时间为5s)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#coding=utf-8 
#!/usr/bin/python
import threading from time
import sleep
import ctime
loops = [3, 5]
#测试函数(没有释放锁的操作)
def loop(nloop, nsec):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:', ctime()

def main():
print 'starting at:', ctime()
threads = []
nloops = range(len(loops))
for i in nloops:
#实例化一个Thread(调用Thread())
#与调用thread.start_new_thread()之间最大的区别就是,新的线程不会立即开始
t = threading.Thread(target=loop, args=(i, loops[i]))
threads.append(t)

#启动线程
for i in nloops:
threads[i].start()

#threading 模块的Thread 类有一个join()函数,允许主线程等待线程的结束
for i in nloops:
threads[i].join()

print 'all DONE at:', ctime()

if __name__ == '__main__':
main()

运行结果:
pythonthreading

threading 模块对象:
Thread 表示一个线程的执行的对象
Lock 锁原语对象(跟thread 模块里的锁对象相同)
RLock 可重入锁对象。使单线程可以再次获得已经获得了的锁(递归锁定)。
Condition 条件变量对象能让一个线程停下来,等待其它线程满足了某个“条件”。如,状态的改变或值的改变。
Event 通用的条件变量。多个线程可以等待某个事件的发生,在事件发生后,所有的线程都会被激活。
Semaphore 为等待锁的线程提供一个类似“等候室”的结构
BoundedSemaphore 与Semaphore 类似,只是它不允许超过初始值
Timer 与Thread 相似,只是,它要等待一段时间后才开始运行。
threading 的Thread 类是你主要的运行对象。它有很多thread 模块里没有的函数。
用Thread 类,可以用多种方法来创建线程。其中有三种比较相像的方法。

  • 创建一个 Thread 的实例,传给它一个函数
  • 创建一个 Thread 的实例,传给它一个可调用的类对象
  • 从 Thread 派生出一个子类,创建一个这个子类的实例

Thread 对象的函数:
start() 开始线程的执行
run() 定义线程的功能的函数(一般会被子类重写)
join(timeout=None) 程序挂起,直到线程结束;如果给了timeout,则最多阻塞timeout 秒
getName() 返回线程的名字
setName(name) 设置线程的名字
isAlive() 布尔标志,表示这个线程是否还在运行中
isDaemon() 返回线程的daemon 标志
setDaemon(daemonic) 把线程的daemon 标志设为daemonic(一定要在调用start()函数前调用) 以下内容摘自《Python核心编程》 核心提示:守护线程 另一个避免使用thread 模块的原因是,它不支持守护线程。当主线程退出时,所有的子线程不 论它们是否还在工作,都会被强行退出。有时,我们并不期望这种行为,这时,就引入了守护线程的概念。
threading 模块支持守护线程,它们是这样工作的:守护线程一般是一个等待客户请求的服务器, 如果没有客户提出请求,它就在那等着。如果你设定一个线程为守护线程,就表示你在说这个线程 是不重要的,在进程退出的时候,不用等待这个线程退出。就像网络编程,服务器线程运行在一个无限循环中,一般不会退出。
如果你的主线程要退出的时候,不用等待那些子线程完成,那就设定这些线程的daemon 属性。 即,在线程开始(调用thread.start())之前,调用setDaemon()函数设定线程的daemon 标志(thread.setDaemon(True))就表示这个线程“不重要”。
如果你想要等待子线程完成再退出, 那就什么都不用做, 或者显式地调用 thread.setDaemon(False)以保证其daemon 标志为False。你可以调用thread.isDaemon()函数来判 断其daemon 标志的值。新的子线程会继承其父线程的daemon 标志。整个Python 会在所有的非守护 线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。

----------------本文结束 感谢阅读----------------