I am currently getting familiar with threading. I noticed a discrepancy when starting a thread using the _thread module package. If attempting to start a thread when not inside a while loop, the calling will be ignored. Note that I am using Windows 11 with Python v.3.13.0. Here is the test script:
print('Starting callable tests.')
import _thread
def action(i): # function run in threads
print(i ** 10)
class Power:
def __init__(self, i):
self.i = i
def action(self): # bound method run in threads
print(self.i ** 32)
# Ignored if while loop is commented out
_thread.start_new_thread(action, (2,)) # simple function
# Comment out the while loop for testing purposes
while True:
_thread.start_new_thread(action, (2,)) # simple function
_thread.start_new_thread((lambda: action(2)), ()) # lambda function to defer
obj = Power(2)
_thread.start_new_thread(obj.action, ()) # bound method object
if input() == 'k': break
print('End of tests.')
Why is this a requirement to start a thread?
On an unrelated note, why does the following pop-up appear when I first start a new topic when I don’t have another window open?
Update:
Apparently, this is observed only when I am testing with PyCharm. If I test with IDLE, it does run:
IDLE test results:
Staring callable tests.
End of tests.1024
PyCharm test results:
Starting callable tests.
End of tests.
Process finished with exit code 0
When I run the script from the CMD prompt, I observe the same results as I do with PyCharm, which is to say that starting the thread function does not work.
Don’t use _thread. It’s a bad idea and you will run into issues like this all the time.
What is happening is that the thread created via _thread.start_new_thread is being executed and started, but the python runtime doesn’t wait for it at exit because it’s not registered in the correct places/doesn’t have correct flags set. That is what threading does for you and is one of the reasons you should use it instead of _thread.
You are seeing different behavior in IDLE, because there the python runtime isn’t terminated at the end of the script - you are instead dropped into a shell and the unregistered background threads can continue to run.
I see. Got it. Thank you for the insight. Yes, if I add the following delay (round about way of forcing it to wait) right after the start function call:
time.sleep(1)
… then I do see the print statement from the function callable.
Yes, the book that I am reading does state that the threading module is recommended over the _thread module package. But since I am just becoming acquainted with these concepts, I wanted to start from the basics and from their work my way up (since concepts carry over to newer / other modules).
But it isn’t true that _thread is more basic. It is an internal implementation detail of CPython. If you want to learn the actual bases, you need to drop down to C - what you learn from _thread is just going to confuse you.
It is the order in which the material is being presented so following along.
It states the following:
Since the basic _thread module is a bit simpler than the more advanced threading
module covered later in this section, let’s look at some of its interfaces first.
Aha, quick googling tells me the book is not supposed to be used for learning python, but as a comprehensive and in depth reference for expereinced programmers. However, it is also quite out-of-date. I would suggest to look at the docs.python.org page for information instead, the book is going to have many gaps for one reason or another.
Yeah, it is a bit outdated - published in 2013. I like it because it explains alot of concepts really well in a structured, sequential manner with plenty of examples. It sure beats hop-skotching around the net. I do hope the author publishes a new up to date edition. The author’s other book, Learnning Python, Edition 6, is coming out in Apri / May. Sure am looking forward to that one (and hopefully gets started on the 5th edition of the book in question ).
Just wanted to make a correction to my original post since after further testing, new information was obtained. It is not the while loop per se that made it work. The reason that it worked with the while loop is because the body contains an input prompt pausing it for enough time (user response time) such that the runtime of the main thread is not terminated prior to the spawned thread runtime.