设为首页 加入收藏

TOP

有关Python中线程的超时控制以及一个简单的应用
2015-08-31 21:25:24 来源: 作者: 【 】 浏览:118
Tags:有关 Python 线程 超时 控制 以及 一个 简单 应用

一、 简单介绍


线程的超时控制在实际的应用中肯定是广泛存在的,比如网络连接超时(socket),文件处理超时等等,但是现在的编程语言貌似都没有很好的处理机制来实现超时管理(也可能是我孤陋寡闻,知道的弟兄不妨赐教下,感激不尽!),一般的说法都是不要特意的去从外部杀死一个线程,退出线程的正确方法是让线程中的run()方法运行结束或者如果run()方法是一个循环在run()方法里面设置一个选项变量来控制循环终止条件(其实还是让run()“自然死亡”)。有些编程语言,比如Python,在其多线程机制里面,如 threading.Thread,根本没有提供终止线程的方法(http://docs.python.org/library/threading.html#thread-objects )。


那么我们怎么让线程超时退出呢,或者说怎么实现超时管理? 其实这需要一点策略。


在说这方面的事情之前,首先了解下怎么在python里面编写多线程的程序,让你的类继承 threading.Thread,并且在类的__init__()方法里面首先调用threading.Thread的__init__()方法,而且你的类必须有一个无参数的run()方法,比如下面的例子:


#!/usr/bin/python
# -*- coding: utf-8 -*-
import threading
########################################################################
class MyThread(threading.Thread):
? ? """A simple threading class."""
? ? #----------------------------------------------------------------------
? ? def __init__(self):
? ? ? ? """Constructor"""
? ? ? ? threading.Thread.__init__(self, name = "Thread-1")
? ? ? ?
? ? #----------------------------------------------------------------------
? ? def run(self):
? ? ? ? """The working method, put all the work of the class in it."""
? ? ? ? print "I am a threading class, my name is: %s " % self.getName()
? ? ? ? print "I am stopping ..."
? ? ? ?
mythread = MyThread()
mythread.start()


二、Python中提供的线程超时检测机制


线程的超时与否可以用Python自己提供的机制来检测, 这就是线程的 join() 函数,在python的文档里面可以找到该函数的详细说明(http://docs.python.org/library/threading.html#threading.Thread.join )。 简单地说,如果同时执行了2个线程t1 和 t2,如果想让一个线程等待另一个线程执行结束再执行的话,那么必须执行被等待线程的join()方法,代码示例如下:


#----------------------------------------------------------------------
def test():
? ? """A task control function."""
? ? ... # previous job
? ? t1 = Thread1()
? ? t2 = Thread2()
? ? t1.start()
? ? t2.start()
? ? t2.join(10) # wait here until t2 is over or timeout occured(10 seconds)
? ? ... # the next job


通过上面的链接查到join()方法的文档可以知道, 该方法有一个可选的参数 timeout,? 如果像上面的例子中设置了该参数的话, 执行了该函数会在此等待t2线程10秒钟,在此期间调用程序(caller)什么也不做,就等着,直到t2结束了或者超时了,才会执行下面的代码。如果不设置timeout参数, caller会在此等待直到t2运行结束。这里需要注意的是, join()函数在这里只相当于一个“采样”,它不会在超时的时候终止t2的执行,实际上t2在超时的情况下还是会执行直到其结束或者另一种情况,caller结束了,但是前提是t2必须被设置为“守护线程(daemon)”(详情见下面的应用实例)。


--------------------------------------分割线 --------------------------------------


--------------------------------------分割线 --------------------------------------


我们只是知道在那里等待了特定的时间再执行下面的代码,那么我们怎么判断t2是否是执行结束了还是线程超时了呢? 这就需要知道线程的"活动(alive)"的概念。大体上,一个线程自从start()方法被调用开始直到run()函数返回的这段期间都被认为是活动的, 而且python提供了一个方法 isAlive()来判断线程是否是活动的。对,就是这样,如果超时了的话,isAlive()方法肯定返回的True(因为join()方法不会结束线程,所以线程仍然是活动的), 而如果是执行结束了,run()函数肯定已经返回了,那么isAlive()方法肯定返回False。代码示例如下:


#----------------------------------------------------------------------
def test():
? ? """A task control function."""
? ? ... # previous job
? ? t1 = Thread1()
? ? t2 = Thread2()
? ? t1.start()
? ? t2.start()
? ? t2.join(10) # wait here until t2 is over or timeout occured(10 seconds)
? ? if t2.isAlive(): # if t2 is still alive, then it is time out!
?print 't2 is time out!'
? ? ... # the next job


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Java获取当前系统时间System.curr.. 下一篇Java 正确遍历字符串

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: