Python Terminated Thread Cannot Restart - python

I have a thread that gets executed when some action occurs. Given the logic of the program, the thread cannot possibly be started while another instance of it is still running. Yet when I call it a second time, I get a "RuntimeError: thread already started" error. I added a check to see if it is actually alive using the Thread.is_alive() function, and it is actually dead.
What am I doing wrong?
I can provide more details as are needed.

Threads cannot be restarted. You must re-create the Thread in order to start it again.

From the Python documentation:
start()
starts the thread's activity.
This must be called at most once per thread object. It arranges for the object's run()method to be invoked in a separate thread of control.
If you derive a class from threading.Thread you can add a Thread.__init__(self) at the end of your run method and you'll be able to call start again and it'll automatically reinitialize itself when done.

You can try setting
thread._Thread__started = False
It isn't officially documented, so use it on your own risk! :)

Related

How to reference a thread in Python 3?

I am trying to call a thread I define in a function from another function. Here is the first function, its purpose is to create and start a thread:
def startThread(func):
listen = threading.Thread(target = func)
listen.start()
I am trying to implement a function that will close the thread created in that first function, how should I go about it? I don't know how to successfully pass the thread.
def endThread(thread):
thread.exit()
Thank you!
This problem is almost FAQ material.
To summarise, there is no way to kill a thread from the outside. You can of course pass the thread object to any function you want, but threading library is missing kill and exit calls.
There are more or less two distinct ways around this, depending on what your thread does.
The first method is to make it so that your thread co-operates. This approach is discussed here: Is there any way to kill a Thread in Python? This method adds a check to your thread loop and a way to raise a "stop signal", which will then cause the thread to exit from the inside when detected.
This method works fine if your thread is a relatively busy loop. If it is something that is blocking in IO wait, not so much, as your thread could be blocking in a read call for days or weeks before receiving something and executing the signal check part. Many IO calls accept a timeout value, and if it is acceptable to wait a couple of seconds before your thread exits, you can use this to force the exit check every N seconds without making your thread a busy loop.
The other approach is to replace threads with processes. You can force kill a subprocess. If you can communicate with your main program with queues instead of shared variables, this is not too complicated, either. If your program relies heavily on sharing global variables, this would require a major redesign.
If your program is waiting in IO loops, you need instantaneous termination and you are using shared global variables, then you are somewhat out of luck, as you either need to accept your threads not behaving nicely or you need to redesign some parts of your code to untangle either the IO wait or shared variables.

Using python thread as a plain object

If i define a python thread extending threading.Thread class and overriding run I can then invoke run() instead of start() and use it in the caller thread instead of a separate one.
i.e.
class MyThread(threading.thread):
def run(self):
while condition():
do_something()
this code (1) will execute "run" method this in a separate thread
t = MyThread()
t.start()
this code (2) will execute "run" method in the current thread
t = MyThread()
t.run()
Are there any practical disadvantages in using this approach in writing code that can be executed in either way? Could invoking directly the "run" of a Thread object cause memory problems, performance issues or some other unpredictable behavior?
In other words, what are the differences (if any notable, i guess some more memory will be allocated but It should be negligible) between invoking the code (2) on MyThread class and another identical class that extends "object" instead of "threading.Tread"
I guess that some (if any) of the more low level differences might depend on the interpreter. In case this is relevant i'm mainly interested in CPython 3.*
There will be no difference in the behavior of run when you're using the threading.Thread object, or an object of a threading.Thread's subclass, or an object of any other class that has the run method:
threading.Thread.start starts a new thread and then runs run in this thread.
run starts the activity in the calling thread, be it the main thread or another one.
If you run run in the main thread, the whole thread will be busy executing the task run is supposed to execute, and you won't be able to do anything until the task finishes.
That said, no, there will be no notable differences as the run method behaves just like any other method and is executed in the calling thread.
I looked into the code implementing threading.Thread class in cpython 3. The init method simply assigns some variables and do not do anything that seems related to actually create a new thread. Therefore we can assume that it should be safe use a threading.Thread object in the proposed manner.

How to keep the daemon threads alive after main thread exits?

I'm working on a python application, in which the main thread creates an object, say x, of a particular class.
Then it starts one thread which starts the execution in one of the methods of this object x. The method has a while True: loop, so its infinite.
Then it starts another thread which starts the execution in another method of the same object x. This method also has a while True: infinite loop.
I have made both the threads as daemon by calling t1.setDaemon(True), but it seems both stop execution once the main thread exits.
How do I keep the children alive after the parent thread is finished?
Or should I change my design to use a cron job or process fork?
The documentation says
A thread can be flagged as a "daemon thread". The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property.
If you want to keep your program running, you must have at least one non daemon thread.

Trying to stop a QThread gracefully, what's wrong with this implementation?

When running my code I start a thread that runs for around 50 seconds and does a lot of background stuff. If I run this program and then close it soon after, the stuff still goes on in the background for a while because the thread never dies. How can I kill the thread gracefully in my closeEvent method in my MianWindow class? I've tried setting up a method called exit(), creating a signal 'quitOperation' in the thread in question, and then tried to use
myThread.quitOperation.emit()
I expected that this would call my exit() function in my thread because I have this line in my constructor:
self.quitOperation.connect(self.exit)
However, when I use the first line it breaks, saying that 'myThread' has no attribute 'quitOperation'. Why is this? Is there a better way?
I'm not sure for python, but I assume this myThread.quitOperation.emit() emits a signal for the thread to exit. The point is that while your worker is using the thread and does not return, nor runs QCoreApplication::processEvents(), myThread will never have the chance to actually process your request (this is called thread starvation).
Correct answer may depend on the situation, and the nature of the "stuff" your thread is doing. The most common practice is that the main thread sends a signal to the worker thread where a slot sets a flag. In the blocking process you regularly check this flag. It it is set you stop whatever "stuff" you are doing, tell your worker thread that it can quit (with a signal preferably with queued connection), call a deleteLater() on the worker object itself, and return from any functions you are currently in, so that the thread's event handler can run, and clear your worker object and itself up, the finally quit.
In case your "stuff" is a huge cycle of very fast operation like simple mathematics or directory navigation one-by-one that takes only a few milliseconds each, this will be enough.
In case your "stuff" contain huge blocking parts that you have no control of (an thus you can't place this flag checking call in it), you may need to wait in the main thread until the worker thread quits.
In case you use direct connect to set the flag, or you set it directly, be sure to protect the read/write access of the flag with a QMutex to prevent inconsistent reads, or user a queued connection to ensure single thread access of the flag.
While highly discouraged, optionally you can use QThread's terminate() method to instantaneously kill the thread. You should never do this as it may cause memory leak, heap corruption, resource leaking and any nasty stuff as destructors and clean-up codes will not run, and the execution can be halted at an undesired state.

thread.join() being called and its not me

I have overrriden the .join() method when creating a subclass of threading.Thread(). When I test my class with a test script it works fine, however when using it in my program the thread.join) method is being called over and over but its not me doing it. What is calling this method? No exception are being thrown as far as i can tell. using inspect the calling functions seems to be _exitfunc but I cant find any info on this.
My code is to long to post but can be found here
If the calling function is _exitfunc that means that the join method is being called at program termination. That is to be expected because the Python threading framework does call join on all running non-daemon threads as part of program termination.
The best explanation of _exitfunc is another Stack Overflow question: What is a python thread
If you don't want join() to be called when program exits, make the thread a daemon:
t.daemon = True
Non-daemon threads will keep the process running until they all die.

Categories