歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

有關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)”(詳情見下面的應用實例)。

--------------------------------------分割線 --------------------------------------

CentOS 6.4安裝 Python2.7.10  http://www.linuxidc.com/Linux/2015-08/120895.htm

無需操作系統直接運行 Python 代碼  http://www.linuxidc.com/Linux/2015-05/117357.htm

CentOS上源碼安裝Python3.4  http://www.linuxidc.com/Linux/2015-01/111870.htm

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

Python 語言的發展簡史 http://www.linuxidc.com/Linux/2014-09/107206.htm

--------------------------------------分割線 --------------------------------------

我們只是知道在那裡等待了特定的時間再執行下面的代碼,那麼我們怎麼判斷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

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-08/121010p2.htm

Copyright © Linux教程網 All Rights Reserved