I have a class that uses the Python Timer class. I was wondering about whether or not I have to manually keep track of the state of the Timer. Namely, I had the following questions:
What happens if start() is called on an already running Timer? Is this the same behavior as the Thread class (which is documented here)?
What happens if cancel() is called on a Timer that is not running?
For the above questions, is the behavior well defined in either case? I can't seem to find the specific details I'm looking for in the docs.
Related
This question already has answers here:
Is there any way to kill a Thread?
(31 answers)
Closed 11 months ago.
While searching for a way to quickly kill a thread when using Python's out-of-the-box threading module, I came across this method: Use the Hidden _stop() Function to Kill a Thread in Python
There is presumably a reason behind why the _stop() function is protected rather than public. My assumption is that it's to make it difficult to terminate a thread unsafely, but I'm curious about whether there are any other reasons.
What are the downsides to calling _stop() to kill a thread?
The code you linked to doesn't call the private ._stop() function at all. Instead the constructor replaces it entirely with an Event:
self._stop = threading.Event()
That appears senseless to me.
The actual private ._stop() function does NOT stop a thread. There is nothing in threading.py that can do so. Instead the private ._stop() function is called internally to maintain Python-level module invariants after the C implementation has determined that a thread's life has (already) ended. There is no case in which it would make sense for user-level code to call it.
EDIT: by the way, in the current Python (>= 3.10), calling ._stop() on a thread that's alive just dies at once with an AssertionError, and that's its only effect. As I recall, in some older Python versions ._stop() went on to corrupt some of threading.py's internals (destroyed its knowledge of which threads were actually still alive). In no case, though, did it ever stop the thread.
How can I have a class in python, that can be run in a separate thread OR be run synchronously. Just to be clear, I have no questions about creating a thread.
If I have a class MyClass(threading.Thread): Then this will always be created as a separate thread, which needs to have its start method called.
I want to avoid duplicating the class again and I'm wondering if I can have the cake and eat it too :)
Side question: Has anyone got python threads to work on kubernetes? Mine just turn into full syncro code. I can't seem to find any resources on this which leads me to think I am doing something very wrong.
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.
I have a very basic Tkinter application that I'm trying to set to automatically refresh. I am using threading.Timer to trigger a function called go at the end of which cocalls the timer to reset it to run again.
def SetTimer():
t=threading.Timer(5,go())
t.start
SetTimer()
I've spent most of my afternoon trying to resolve this but I can't seem to figure out what I'm doing wrong. Based upon the other questions I've read I understand that each instance creates a separate thread with the timer, but why isn't it waiting for the time to elapse prior to triggering the function.
Use:
t=threading.Timer(5,go)
Note the go rather than go(). The parentheses tell Python to call the function. In contrast, go is a function object. Functions are "first-class" objects in Python; they can be passed to functions just like any other object.
Python evaluates the arguments to a function before calling the function. So using go() calls the go before calling threading.Timer. The value returned by go() gets sent to Timer, which is not what you want.
Note that all Tkinter UI code should be called from a single thread. For this reason, using Tkinter's root.after method is probably a better choice for what you want to do. The after method schedules a function to be called by Tkinter's mainloop. Here are some examples using after:
Tkinter and Threads
A rotating image
I am relatively new to Python but am using it to hack together some automation. I am having a bit of trouble with Classes and how functions within speak to functions outside. My real goal is to create a thread out of an existing function without requiring a rewrite of most of my code.
Here is my current model. I have a super class AppWindow(wx.Frame) and within it there are many functions defined.
InitUI creates the interface and initializes variables.
ProcessComputers reaches out to different workstations to gather some info. This relies heavily on a module I had written when this application was console-based.
There are various other misc. functions that aren't really worth calling out.
This obviously is bad for the GUI since everything is dependent on those processes completing before the screen can refresh and accept events.
Since ProcessComputer is already separate from my UI functions, I am wondering what is the easiest way to move these functions into a separate thread, without having to rewrite and rename objects and variables?
I have tried creating a new class as suggested here. The problem is when I created the two new classes, and move the guts of ProcessComputer to the CountEvent class, everything broke. I could no longer update a self.textField from AppWindow nor could I refer to it using AppWindow.textField. None of my variables were accessible to the new class. Is there a better way of moving this function into its own class, without rewriting too much of the code that is currently working?
If not, what is the best way of rewriting the guts of ProcessComputer so they still play with the rest of the code within AppWindow?
I would leave the ProcessComputer function where it's at and have your GUI call it. But put its guts into a function in a class that's based on Thread. Then when you need to update the GUI, you'll have to call one of wxPython's thread-safe methods: wx.CallAfter, wx.CallLater or wx.PostEvent.
Here are a couple of good resources:
http://wiki.wxpython.org/LongRunningTasks
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
This is kind of what your thread class will look like:
########################################################################
class TestThread(Thread):
"""Test Worker Thread Class."""
#----------------------------------------------------------------------
def __init__(self, wxObject):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.wxObject = wxObject
self.start() # start the thread
#----------------------------------------------------------------------
def run(self):
"""Run Worker Thread."""
# This is the code executing in the new thread.
for i in range(6):
time.sleep(10)
amtOfTime = (i + 1) * 10
wx.PostEvent(self.wxObject, ResultEvent(amtOfTime))
time.sleep(5)
wx.PostEvent(self.wxObject, ResultEvent("Thread finished!"))
The rest of the code can be similar to the example in the 2nd link. Or you can use the first link to the wiki to see a couple of other approaches.