|
First, a brief introduction
Thread timeout control in practical applications is certainly widespread, such as network connection timeout (socket), document processing timeouts, etc., but now looks like a programming language are not a good deal timeout mechanisms to achieve management (and possibly I am ignorant, brethren wish to know under the wing, grateful!), the general argument is not deliberately to kill a thread from the outside, the proper way to exit a thread is to thread run () method or if the end of the run run () method is an option to set a loop variable in the run () method which controls the loop termination condition (actually let run () "natural death"). Methods Some programming languages, such as Python, in which multi-threaded mechanism, such as threading.Thread, did not provide termination of threads (http://docs.python.org/library/threading.html#thread-objects).
So how do we make the timeout thread exits it, or how to implement timeouts management? In fact, it takes a little strategy.
Before saying this thing, at first understand how to write in python inside multi-threaded program that lets you inherit threading.Thread class, and the class __init __ () method which is called first threading.Thread the __init __ () method, and your class must have a no-argument run () method, as in the following example:
#! / 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 ()
Two, Python provides thread timeout detection mechanism
Thread timeout or not you can use to provide their own mechanism to detect Python, this is the thread's join () function, in the document which python can find detailed descriptions of the function (http://docs.python.org/library/threading .html # threading.Thread.join). Simply put, if two threads simultaneously executed t1 and t2, if you want a thread to wait for another thread of execution before the end of the execution, then you must do is to wait for the thread join () method, the code examples are as follows:
# ------------------------------------------------- ---------------------
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
Through the above link to find join () method of the document can be known, this method has an optional parameter timeout, if, as the above example this parameter is set, then the function will be performed in this thread waits for t2 10 seconds during this period the caller (caller) do nothing, just wait until the end of t2 or overtime, and will execute the following code. If you do not set the timeout parameters, caller will wait here until the end of t2 run. It should be noted that, join () function here only acts as a "sampling", which does not terminate execution t2 in overtime when, in fact t2 in the case of a timeout would be executed until it ends or another case, caller over, but the premise is t2 must be set to "daemon thread (daemon)".
We just know where to wait for a specific time and then execute the following code, then how do we judge whether t2 is executed or the end of a timeout thread of it? This thread needs to know the concept of "active (alive)" of. In general, a thread since the start () method is called the beginning until the run () function returns the period are considered to be active, but also provides a method for python isAlive () to determine whether the thread is active. Yes, exactly, if timed out, then, isAlive () method certainly return True (because the join () method is not the end of the thread, the thread is still active), and if the implementation of the end, run () function must have Back, then isAlive () method certainly return False. Code examples are as follows:
# ------------------------------------------------- ---------------------
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
Third, application examples
Timeouts and python basic time-out processing in the above has been given for the reader, in this section I will describe a simple example of a time-out control and management. In this example, I will have 10 special forces team to perform the task of the assassination of terrorists, everyone has their own assassination target, your goals must kill considered bin! Everyone time to perform the task is certainly not the same, but the helicopter retreated only waiting for a specific time to take off, which means that surely someone can not retreat because of a timeout, timeout people perform task failed!
Class 1: Soldier, mission class. There are two parameters in this class which has played a vital role and that is isStopped isSuccess, which indicates that this class is the implementation of the end, which illustrate the class is executed successfully. In addition, isStopped is also used to determine whether this class is a timeout, I'm not here said earlier isAlive () function to determine, because the isAlive () function of time is too strict, and I need to make a class set up their own whether to stop mark (class I've seen has been running over, but isAlive () function returns True or case). Every Soldier class call setDaemon (True) method is set to daemon thread (daemon), so-called daemon threads, that is, in the case where the caller is finished, the thread will end, otherwise the thread will continue until its real execution End. Soldier classes are as follows:
#! / Usr / bin / python
# - * - Coding: utf-8 - * -
import os, sys, re, math
import threading
import time
import random
################################################## ######################
class Soldier (threading.Thread):
"" "The class of a soldier." ""
# ------------------------------------------------- ---------------------
def __init __ (self, name):
"" "Constructor" ""
threading.Thread .__ init __ (self, name = name)
self.name = name # the name of this soldier
self.setDaemon (True) # this is a daemon thread.
# The time of this soldier need to finish the job
self.playTime = random.randint (1,10)
# Is the soldier stop shotting, if timeout or the target has been killed,
# I may stop.
self.isStopped = False
self.isSuccess = False # did he kill the target?
# ------------------------------------------------- ---------------------
def assassinate (self):
"" "The task, to kill the target." ""
for i in range (self.playTime):
print '% s play (% d)'% (self.name, i + 1)
time.sleep (1)
# ------------------------------------------------- ---------------------
def run (self):
"" "Start to move ..." ""
print '% s has moved out, need time:% d ...'% (self.name, self.playTime)
self.assassinate ()
print '% s stopped ...'% self.name
self.isStopped = True # the target has been killed, then he stopped.
self.isSuccess = True
Class 2: Commander, Command Soldier class. This class is not to increase the dramatic effect and deliberately added, but this class is a must. Class mission requires a center for the caller to call join () method to determine whether a timeout. Yes caller can also call the turn when the workers begin their classes join () method to determine the timeout, but then, every call to join () are required to wait the equivalent of thread is not performed together but one by one performed. Therefore, the design of a middle class calls for each worker class is a must, caller calls in turn starts the middle class, so these classes run together, then all of the workers in the class is working together, this is a multi-threaded. Commander class as follows:
################################################## ######################
class Commander (threading.Thread):
"" "The class of commander, a commander will command only one soldier." ""
# ------------------------------------------------- ---------------------
def __init __ (self, soldier):
"" "Constructor" ""
threading.Thread .__ init __ (self, name = 'Commander')
self.soldier = soldier
# ------------------------------------------------- ---------------------
def run (self):
"" "Authorize the soldier to start killing." ""
self.soldier.start ()
try:
# Boss said: give the soldier 5 seconds to finish his job
self.soldier.join (5)
except:
pass
# Use the class's own attribute to judge whether it is timeout.
#if self.soldier.isAlive ():
if not self.soldier.isStopped:
print '% s is timeout!'% self.soldier.name
# The soldier run out his time, then he stopped.
self.soldier.isStopped = True
Caller: perform all the work, including the initialization workers and the middle class call the class to the specified time to perform inspection results, etc., caller code is as follows:
# ------------------------------------------------- ---------------------
def killing ():
"" "Let's pull the trigger, start killing!" ""
t1 = time.time ()
# Get ready for the commanders
l_commander = []
for i in range (10): # 10 soldiers
# Get ready for the soldier
soldier = Soldier (% 'soldier-% d' (i + 1))
if i == 5 or i == 9:
soldier.playTime = 10000
l_commander.append (Commander (soldier))
# Soldiers move out one by one.
for cmd in l_commander:
cmd.start ()
# Judge whether the helicopter should go. If all the soldiers are stop,
# That is, all finished job or timeout, then it should go!
isBreak = False
while not isBreak:
isBreak = True
for cmd in l_commander:
if cmd.soldier.isStopped == False:
isBreak = False
# Check the results of the battle at the schedule time.
for cmd in l_commander:
print '% s, is success:% s'% (cmd.soldier.name, cmd.soldier.isSuccess)
# Go back to base.
time.sleep (20)
# Check the results at the final time.
for cmd in l_commander:
print '% s, is success:% s'% (cmd.soldier.name, cmd.soldier.isSuccess)
t2 = time.time ()
print 'Total time:% .2f'% (float (t2-t1))
In the caller, use a while loop to wait for all the threads stop control without executing the following code, once all the threads stop, and check the result.
Executive killing () function has the following results:
soldier-1 has moved out, need time: 2 ...
soldier-1 play (1)
soldier-2 has moved out, need time: 6 ...
soldier-2 play (1)
soldier-3 has moved out, need time: 3 ...
soldier-3 play (1)
soldier-4 has moved out, need time: 4 ...
soldier-4 play (1)
soldier-5 has moved out, need time: 9 ...
soldier-5 play (1)
soldier-6 has moved out, need time: 10000 ...
soldier-6 play (1)
soldier-7 has moved out, need time: 8 ...
soldier-7 play (1)
soldier-8 has moved out, need time: 10 ...
soldier-8 play (1)
soldier-9 has moved out, need time: 7 ...
soldier-9 play (1)
soldier-10 has moved out, need time: 10000 ...
soldier-10 play (1)
soldier-3 play (2)
soldier-2 play (2)
soldier-4 play (2)
soldier-1 play (2)
soldier-6 play (2)
soldier-7 play (2)
soldier-5 play (2)
soldier-8 play (2)
soldier-9 play (2)
soldier-10 play (2)
soldier-1 stopped ...
soldier-3 play (3)
soldier-2 play (3)
soldier-7 play (3)
soldier-6 play (3)
soldier-5 play (3)
soldier-4 play (3)
soldier-8 play (3)
soldier-9 play (3)
soldier-10 play (3)
soldier-7 play (4)
soldier-6 play (4)
soldier-3 stopped ...
soldier-4 play (4)
soldier-2 play (4)
soldier-8 play (4)
soldier-5 play (4)
soldier-9 play (4)
soldier-10 play (4)
soldier-7 play (5)
soldier-6 play (5)
soldier-4 stopped ...
soldier-2 play (5)
soldier-8 play (5)
soldier-5 play (5)
soldier-9 play (5)
soldier-10 play (5)
soldier-6 is timeout!
soldier-2 is timeout!
soldier-7 is timeout!
soldier-8 is timeout!
soldier-5 is timeout!
soldier-7 play (6)
soldier-6 play (6)
soldier-2 play (6)
soldier-8 play (6)
soldier-5 play (6)
soldier-9 is timeout!
soldier-9 play (6)
soldier-10 is timeout!
soldier-1, is success: True
soldier-2, is success: False
soldier-3, is success: True
soldier-4, is success: True
soldier-5, is success: False
soldier-6, is success: False
soldier-7, is success: False
soldier-8, is success: False
soldier-9, is success: False
soldier-10, is success: False
soldier-10 play (6)
soldier-7 play (7)
soldier-6 play (7)
soldier-2 stopped ...
soldier-8 play (7)
soldier-5 play (7)
soldier-9 play (7)
soldier-10 play (7)
soldier-7 play (8)
soldier-6 play (8)
soldier-8 play (8)
soldier-5 play (8)
soldier-9 stopped ...
soldier-10 play (8)
soldier-7 stopped ...
soldier-6 play (9)
soldier-8 play (9)
soldier-5 play (9)
soldier-10 play (9)
soldier-6 play (10)
soldier-5 stopped ...
soldier-8 play (10)
soldier-10 play (10)
soldier-6 play (11)
soldier-8 stopped ...
soldier-10 play (11)
soldier-6 play (12)
soldier-10 play (12)
soldier-6 play (13)
soldier-10 play (13)
soldier-6 play (14)
soldier-10 play (14)
soldier-6 play (15)
soldier-10 play (15)
soldier-6 play (16)
soldier-10 play (16)
soldier-6 play (17)
soldier-10 play (17)
soldier-6 play (18)
soldier-10 play (18)
soldier-6 play (19)
soldier-10 play (19)
soldier-6 play (20)
soldier-10 play (20)
soldier-6 play (21)
soldier-10 play (21)
soldier-6 play (22)
soldier-10 play (22)
soldier-6 play (23)
soldier-10 play (23)
soldier-6 play (24)
soldier-10 play (24)
soldier-6 play (25)
soldier-10 play (25)
soldier-6 play (26)
soldier-1, is success: True
soldier-2, is success: True
soldier-3, is success: True
soldier-4, is success: True
soldier-5, is success: True
soldier-6, is success: False
soldier-7, is success: True
soldier-8, is success: True
soldier-9, is success: True
soldier-10, is success: False
Total time: 25.05
The results are displayed in 5 seconds, when the inspection results and only 1, 3 and 4 the successful completion of the task, the other out. Then, returning to the ground inside 20 seconds, the other unfinished threads did not stop, but continue to work after 20 seconds, caller has ended, note that all worker threads have been set to daemon thread , so when the end of the caller, also followed the end. The caller, in order to illustrate mission class to distinguish daemon thread and non-daemon threads, I have come to make 6 and 10 players time increases, so time at the end will be the end of the inspection victories, 6, and 10 did not complete , still out.
If the Soldier class self.setDaemon (True) commented, then 6 and 10 will continue to be run when the caller's end, which really run until the end of 10000 seconds later.
IV Summary
Timeout control and processing threads is a very useful technique, usually will use a lot. Using the detection method python itself providing and self-defined controls, we can achieve a good timeout control and management. In the case of the third part of this paper, I show a strategy of control of overtime that workers call the class + class + caller's model, each attribute which is the basis of this model inside and necessary. This model is currently being applied in my own project above, on this project, you need to use a lot of ways to deal with a computer proteins, each method is equivalent to the inside of the Soldier class examples in this article, a caller needs to give each method the results then were analyzed. In order to prevent the execution time of the whole system is a method of dragging long timeout control must be carried out for each of the processing method of the protein, which in a specified time if the method does not give results, automatically ignored. |
|
|
|