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

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

#coding=utf-8
#!/usr/bin/python

import threading
from time import sleep, 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 类,可以用多种方法来创建线程。在这里介绍三种比较相像的方法。可以任选一种喜欢的,或最适合的程序以及最能满足程序可扩展性的:

1、创建一个 Thread 的实例,传给它一个函数
2、创建一个 Thread 的实例,传给它一个可调用的类对象
3、从 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 会在所有的非守护
线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。

转载请注明出处:http://www.xiaomastack.com/2014/07/17/pythonthreading/ 谢谢!

发表评论:

你的电子邮件地址将不会被公开.

− 3 = 5