Colin Sergi
Colin Sergi

Reputation: 134

Python thread run() blocking

I was attempting to create a thread class that could be terminated by an exception (since I am trying to have the thread wait on an event) when I created the following:

import sys

class testThread(threading.Thread):
    def __init__(self):
        super(testThread,self).__init__()
        self.daemon = True

    def run(self):
        try:
            print('Running')
            while 1:
                pass
        except:
            print('Being forced to exit')

test1 = testThread()
test2 = testThread()

print(test1.daemon)
test1.run()
test2.run()

sys.exit()

However, running the program will only print out one Running message, until the other is terminated. Why is that?

Upvotes: 4

Views: 5707

Answers (1)

abarnert
abarnert

Reputation: 365767

The problem is that you're calling the run method.

This is just a plain old method that you implement, which does whatever you put in its body. In this case, the body is an infinite loop, so calling run just loops forever.

The way to start a thread is the start method. This method is part of the Thread class, and what it does is:

Start the thread’s activity.

It 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.

So, if you call this, it will start a new thread, make that new thread run your run() method, and return immediately, so the main thread can keep doing other stuff.1 That's what you want here.


1. As pointed out by Jean-François Fabre, you're still not going to get any real parallelism here. Busy loops are never a great idea in multithreaded code, and if you're running this in CPython or PyPy, almost all of that busy looping is executing Python bytecode while holding the GIL, and only one thread can hold the GIL at a time. So, from a coarse view, things look concurrent—three threads are running, and all making progress. But if you zoom in, there's almost no overlap where two threads progress at once, usually not even enough to make up for the small scheduler overhead.

Upvotes: 7

Related Questions