Stopping a Thread After a Certain Amount of Time

Most Pythonic way to kill a thread after some period of time

Using an Event in this case is works just fine as the signalling mechanism, and
is actually recommended in the threading module docs.

If you want your threads to stop gracefully, make them non-daemonic and use a
suitable signalling mechanism such as an Event.

When verifying thread termination, timeouts almost always introduce room for
error. Therefore, while using the .join() with a timeout for the initial
decision to trigger the event is fine, final verification should be made using a
.join() without a timeout.

# wait 30 seconds for the thread to finish its work
t.join(30)
if t.is_alive():
print "thread is not done, setting event to kill thread."
e.set()
# The thread can still be running at this point. For example, if the
# thread's call to isSet() returns right before this call to set(), then
# the thread will still perform the full 1 second sleep and the rest of
# the loop before finally stopping.
else:
print "thread has already finished."

# Thread can still be alive at this point. Do another join without a timeout
# to verify thread shutdown.
t.join()

This can be simplified to something like this:

# Wait for at most 30 seconds for the thread to complete.
t.join(30)

# Always signal the event. Whether the thread has already finished or not,
# the result will be the same.
e.set()

# Now join without a timeout knowing that the thread is either already
# finished or will finish "soon."
t.join()

Stop the thread after a particular time

User a Timer and a flag to tell the thread to stop:

public class MyRunnableThread implements Runnable {

boolean run = true;

String fname;

public MyRunnableThread(String fname) {
this.fname = fname;
}

public void setRun(boolean toSet) {
run = false;
}

public void run() {
while (run) {
doStuff();
}
}

private void doStuff() {
// File.read(fname);
}
}

How to use it:

import java.util.Timer;
import java.util.TimerTask;

public class Tester {

public static void main(String args[]) {

String[] fname = { "file1.txt", "file2.txt", "file3.txt", "file4.txt", "file5.txt" };
for (int i = 0; i < 5; i++) {
try {

MyRunnableThread mrt = new MyRunnableThread(fname[i]);
Thread t = new Thread(mrt);
t.start();

final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int i = 6; // Time in seconds

public void run() {
System.out.println(i--);
if (i < 0) {
timer.cancel();
mrt.setRun(false);
}
}
}, 0, 1000);

} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Change i to whatever time in seconds you want

Stopping a thread after a certain amount of time

This will work if you are not blocking.

If you are planing on doing sleeps, its absolutely imperative that you use the event to do the sleep. If you leverage the event to sleep, if someone tells you to stop while "sleeping" it will wake up. If you use time.sleep() your thread will only stop after it wakes up.

import threading
import time

duration = 2

def main():
t1_stop = threading.Event()
t1 = threading.Thread(target=thread1, args=(1, t1_stop))

t2_stop = threading.Event()
t2 = threading.Thread(target=thread2, args=(2, t2_stop))

time.sleep(duration)
# stops thread t2
t2_stop.set()

def thread1(arg1, stop_event):
while not stop_event.is_set():
stop_event.wait(timeout=5)

def thread2(arg1, stop_event):
while not stop_event.is_set():
stop_event.wait(timeout=5)

Java 8: Kill/Stop a thread after certain period of time

You are correct with your approach.
calling cancel(true); on future is the right way to stop this task.

You have another problem- you cannot just stop a thread. (well you can, using stop() in thread class, but you should never do this).

cancel(true); sends information to the thread, that it should be stopped. Some java classes are responding to this information and throw interrupted exception. But some dont. You have to modify your task code, to check if Thread.currentThread().isInterrupted(), and if so, stop execution.

This is something you have to do in your code, which you call by

  jobareaDeciderSample w = new jobareaDeciderSample();
w.mainSample(url, c, con);

You should do this in some long time spinning code, if you said you do some stuff with url, you should do it in your while loop, where you download information for the web. In other words, do this check only when your code spends 99% of the time.

Also you are calling

        Thread.currentThread().interrupt();

in your main thread, this does not do anything for you, as if you want to quit current thread, you can just call return

Stop a thread after period of time

There is no unique answer to your question. It depends on what the thread does. First of all, how do you plan to stop that thread?

  1. If it elaborates some stuff, and this stuff is made of "tokens" such as single "tasks" to do, and the thread grabs them from a BlockingQueue for example, then you can stop the thread with a so-called "poison pill", like a mock task that the thread reads as: "Hey man, I have to shut down".
  2. If the thread does something which cannot be "divided" into "steps" then you should actually tell us how do you think it can be shut down. If it blocks on read()s on a socket, you can only close the socket to unblock it.

Please note interrupt() is not meant to stop a Thread in normal circumstances, and if you interrupt() a thread, in most cases it'll just go on doing its stuff. In 99.9% of cases, it is just bad design to stop a thread with interrupt().

Anyway, to stop it after 5 seconds, just set a Timer which does so. Or better join it with a timeout of 5 seconds, and after that, stop it. Problem is "how" to stop it. So please tell me how do you think the thread should be stopped so that I can help you in better way.

Tell me what the thread does.

EDIT: in reply to your comment, just an example

class MyHTTPTransaction extends Thread {
public MyHTTPTransaction(.....) {
/* ... */
}
public void run() {
/* do the stuff with the connection */
}
public void abortNow() {
/* roughly close the connection ignoring exceptions */
}
}

and then

MyHTTPTransaction thread = new MyHTTPTransaction(.....);
thread.start();
thread.join(5000);
/* check if the thread has completed or is still hanging. If it's hanging: */
thread.abortNow();
/* else tell the user everything went fine */

:)

You can also set a Timer, or use Condition on Locks because I bet there can be some race condition.

Cheers.

How to kill a thread after N seconds?

As I said in a comment you can't really "kill" a thread (externally). However they can "commit suicide" by returning or raising a exception.

Below is example of doing the latter when the thread's execution time has exceeded a given amount of time. Note that this is not the same as doing a join(timeout) call, which only blocks until the thread ends or the specified amount of time has elapsed. That's why the printing of value and its appending to the list happens regardless of whether the thread finishes before the call to join() times-out or not.

I got the basic idea of using sys.settrace() from the tutorial titled Different ways to kill a Thread — although my implementation is slightly different. Also note that this approach likely introduces a significant amount of overhead.

import sys
import threading
import time

class TimelimitedThread(threading.Thread):
def __init__(self, *args, time_limit, **kwargs):
self.time_limit = time_limit
self._run_backup = self.run # Save superclass run() method.
self.run = self._run # Change it to custom version.
super().__init__(*args, **kwargs)

def _run(self):
self.start_time = time.time()
sys.settrace(self.globaltrace)
self._run_backup() # Call superclass run().
self.run = self._run_backup # Restore original.

def globaltrace(self, frame, event, arg):
return self.localtrace if event == 'call' else None

def localtrace(self, frame, event, arg):
if(event == 'line' and
time.time()-self.start_time > self.time_limit): # Over time?
raise SystemExit() # Terminate thread.
return self.localtrace

THREAD_TIME_LIMIT = 2.1 # Secs
threads = []
my_list = []

def foo(value):
global my_list
time.sleep(value)
print("Value: {}".format(value))
my_list.append(value)

for i in range(5):
th = TimelimitedThread(target=foo, args=(i,), time_limit=THREAD_TIME_LIMIT)
threads.append(th)

for th in threads:
th.start()

for th in threads:
th.join()

print('\nResults:')
print('my_list:', my_list)

Output:

Value: 0
Value: 1
Value: 2

Results:
my_list: [0, 1, 2]

Killing thread after some specified time limit in Java

Make use of ExecutorService to execute the Callable, checkout the methods wherein you can specify the timeout. E.g.

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();

Here Task of course implements Callable.



Related Topics



Leave a reply



Submit