Python thread close all

Closing all threads with a keyboard interrupt

What I’m trying to do here is use a keyboard interrupt to exit all ongoing threads in the program. This is a pared down version of my code where the thread is created:

for i in taskDictionary: try: sleep(60) thread = Thread(target = mainModule.executeThread) thread.start() except KeyboardInterrupt: thread.__stop() 

The program itself is far more complicated, accounting for tons of different variables that affect the threads and even having the option to launch in a sequential mode, where tasks are not threaded, but instead launched one-by-one so there might be some problems with this small variation I just conjured up. I have done this in ways that produced 50/50 results. The interrupts would work but the threads would never cleanly exit. Sometimes they would keep going but halt the execution of future threads, some times they would exit with a massive error regarding the interrupt, other times the interrupts would do nothing at all. Last time I ran this the program stopped any future threads from executing but did not stop the current thread. Is there any way to exit the threads without going into the module the thread is actually executing in?

2 Answers 2

A similar question is «How do you kill a thread?»

You create an exit handler in your thread that is controlled by a lock or event object from the threading module. You then simply remove the lock or signal the event object. This informs the thread it should stop processing and exit gracefully. After signaling the thread in your main program, the only thing left to do is to use the thread.join() method in main which will wait for the thread to shut down.

import threading import time def timed_output(name, delay, run_event): while run_event.is_set(): time.sleep(delay) print name,": New Message!" def main(): run_event = threading.Event() run_event.set() d1 = 1 t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event)) d2 = 2 t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event)) t1.start() time.sleep(.5) t2.start() try: while 1: time.sleep(.1) except KeyboardInterrupt: print "attempting to close threads. Max wait =",max(d1,d2) run_event.clear() t1.join() t2.join() print "threads successfully closed" if __name__ == '__main__': main() 

If you REALLY need the functionality of killing a thread, use multiprocessing. It allows you to send SIGTERMs to individual «processes» (it’s also very similar to the threading module). Generally speaking, threading is for when you are IO-bound, and multiprocessing is for when you are truly processor-bound.

Читайте также:  Theme name style css

Источник

How can I kill all threads?

Is it possible to kill all threads in the except of KeyboardInterrupt? I’ve searched on the net and yeah, I know that it has been already asked, but I’m really new in python and I didn’t get so well the method of these other question asked on stack.

You want to kill all threads. does this include the main thread and as a consequence, the application? If so, simply make all your threads daemons and then when you want to quit, use sys.exit() .

@CristiFati: That won’t help if the KeyboardInterrupt is delivered to one of the threads (the thread that receives it is basically random IIRC). Thus the need for alerting the main thread so it can exit at the appropriate time.

Right @ShadowRanger, thank you for pointing it out, threads tend to swallow exceptions. As a note, when I’m dealing with threads, I use the reverse approach: in a thread’s loop, if a key was pressed (the logic can be expanded based on key), end it.

No way ! Socket is external thread. Set a timeout value for auto kill. How to handle *socket.error ? while True is bad idea, while some_status_bolean better !

3 Answers 3

No. Individual threads can’t be terminated forcibly (it’s unsafe, since it could leave locks held, leading to deadlocks, among other things).

Two ways to do something like this would be to either:

  1. Have all threads launched as daemon threads, with the main thread waiting on an Event / Condition and exiting as soon as one of the threads sets the Event or notifies the Condition . The process terminates as soon as the (sole) non- daemon thread exits, ending all the daemon threads
  2. Use a shared Event that all the threads poll intermittently, so they cooperatively exit shortly after it is set.

thanks for answer. I’ve seen the 2 way here: stackoverflow.com/questions/323972/… but I really don’t know how to implement it to my send() class.

@allexj: You can’t kill threads, like I already said. Use a shared Event , change while True: to while not myevent.is_set(): , and stop using a bare except inside the loop (it will catch KeyboardInterrupt preventing you from processing it; catch Exception or the like). Then when you catch KeyboardInterrupt , call myevent.set() to tell all the other threads to stop processing on their next loop. This is not that hard to adapt, try playing around with it if it doesn’t work immediately.

As a comment said, use exit(n) to terminate a threads, but it might not terminate all threads necessarily and threads will mostly continue to run.

So your approach is to use os._exit(n) , This terminates all threads and does what you want.

But be warned os._exit is not a good way to exit a script, and should be used only in special cases.

@Allexj: You got an accurate answer from @ShadowRanger. You can do it as shown below.

import threading, socket, sys event = Threading.Event() # define an Event class send(threading.Thread): def run(self): try: global event while True: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((url,port)) s.send(b"Hello world!") print ("Request Sent!") except: s.close() except KeyboardInterrupt: # here i'd like to kill all threads if possible event.set() # set the event as soon as any thread receives an keyboardInterrupt. try: for x in range(800): send(daemon=True).start() event.wait() except KeyboardInterrupt: # If user pressed ctrl+c while loop was still running, then this will be useful pass sys.exit(0) 

Источник

python thread terminate or kill in the best way

The thing is I want to kill all the thread that are currently running.For example I have a single button whose calling the for loop. and suddenly I want to stop it. here are my codes:

class WorkerThread(threading.Thread): def __init__(self,t,*args): super(WorkerThread,self).__init__(target=t,args=(args[0],args[3])) self.start() self.join() 
def running(fileopen,methodRun): #. long task of code are here. for file in fileTarget: threads.append(WorkerThread(running,file,count,len(fileTarget),"FindHeader")) 

set a boolean flag that locks the thread execution block, soon or later you can change the state of the flag, letting the thread to finish its run method cleanly.

hi sir, thank you for your suggestion could you show some codes to handle that? 2 to 4 lines of code will do.

1 Answer 1

Never try to abruptly terminate a thread. Instead setup a flag/signal in your WorkerThread class, and then when you want it to stop just set the flag and make the thread finish by itself.

Also you have misunderstandings on how to subclass threading.Thread . If you decide to run a function as thread, it should be:

thread = threading.Thread(target=my_func, args=(arg1, arg2. )) thread.start() 

Well, in your case this won’t fit for your needs since you want the thread to stop when requested. So now let’s subclass threading.Thread , basically __init__ is like a constructor in python, every time when an instance is created it’ll get executed. And you immediately start() the thread and then block it with join() , what it does is in your for loop threads.append(WorkerThread(running,file,count,len(fileTarget),»FindHeader»)) will block till the end of running finished with file and then goes on to work with another file , no actual thread is being used.

You should move your running(fileopen,methodRun) into run() :

class WorkerThread(threading.Thread): def __init__(self,*args): super(WorkerThread,self).__init__() self.arg_0 = arg[0] self.arg_1 = arg[1] . self.stop = False def run(self): # now self.arg_0 is fileopen, and self.arg_1 is methodRun # move your running function here #. long task of code are here. Try to do self.stop check every small interval, e.g. . if self.stop: return . for file in fileTarget: new_thread = WorkerThread(file, count, len(fileTarget), "FindHeader")) new_thread.start() threads.append(new_thread) # Stop these threads for thread in threads: thread.stop = True 

Источник

How to exit the entire application from a Python thread?

How can I exit my entire Python application from one of its threads? sys.exit() only terminates the thread in which it is called, so that is no help. I would not like to use an os.kill() solution, as this isn’t very clean.

I know you don’t want one, but for those who do want an os.kill() solution, you could do os.kill(os.getpid(), signal.SIGTERM) ; be sure to import os and signal first, of course. This is nice because it lets you break out of input statements in the main thread from another thread to quit the program.

5 Answers 5

I yanked and slightly modified a simple threading example from a tutorial on DevShed:

import threading, sys, os theVar = 1 class MyThread ( threading.Thread ): def run ( self ): global theVar print 'This is thread ' + str ( theVar ) + ' speaking.' print 'Hello and good bye.' theVar = theVar + 1 if theVar == 4: #sys.exit(1) os._exit(1) print '(done)' for x in xrange ( 7 ): MyThread().start() 

If you keep sys.exit(1) commented out, the script will die after the third thread prints out. If you use sys.exit(1) and comment out os._exit(1) , the third thread does not print (done) , and the program runs through all seven threads.

os._exit «should normally only be used in the child process after a fork()» — and a separate thread is close enough to that for your purpose. Also note that there are several enumerated values listed right after os._exit in that manual page, and you should prefer those as arguments to os._exit instead of simple numbers like I used in the example above.

This works especially well when running in a docker container. The issue in a docker container is that we can’t kill pid 1. Using os._exit(1) worked.

If all your threads except the main ones are daemons, the best approach is generally thread.interrupt_main() — any thread can use it to raise a KeyboardInterrupt in the main thread, which can normally lead to reasonably clean exit from the main thread (including finalizers in the main thread getting called, etc).

Of course, if this results in some non-daemon thread keeping the whole process alive, you need to followup with os._exit as Mark recommends — but I’d see that as the last resort (kind of like a kill -9 😉 because it terminates things quite brusquely (finalizers not run, including try/finally blocks, with blocks, atexit functions, etc).

Using thread.interrupt_main() may not help in some situation. KeyboardInterrupt s are often used in command line applications to exit the current command or to clean the input line.

In addition, os._exit will kill the process immediately without running any finally blocks in your code, which may be dangerous (files and connections will not be closed for example).

The solution I’ve found is to register a signal handler in the main thread that raises a custom exception. Use the background thread to fire the signal.

import signal import os import threading import time class ExitCommand(Exception): pass def signal_handler(signal, frame): raise ExitCommand() def thread_job(): time.sleep(5) os.kill(os.getpid(), signal.SIGUSR1) signal.signal(signal.SIGUSR1, signal_handler) threading.Thread(target=thread_job).start() # thread will fire in 5 seconds try: while True: user_input = raw_input('Blocked by raw_input loop ') # do something with 'user_input' except ExitCommand: pass finally: print('finally will still run') 

Источник

Оцените статью