Multi-Threading in Python - Not re-running a thread that's already going

Wang191

[H]ard|Gawd
Joined
Nov 30, 2000
Messages
2,026
I'm creating a script that runs in a loop over and over again to check when a button is pressed.

When the button is pressed the script polls my website for a specific value. If the value is 1 then a light turns red. If the value is 2 then the light turns blue. It's pretty simplistic. The problem I'm running into is that the function that polls the website runs as a thread because I want the web checking part of the script to "peel off" and not halt my loop just in case the web request takes a while to occur due to network issues or any other issues.

Where I'm running into trouble is that if a user presses the button 10 times really quickly I don't want 10 threads to all of a sudden pop up. I want the button to try triggering the same thread so that if it's already running it just continues. If the thread has already stopped then it just starts up again. I don't quite understand the examples I'm seeing to get that part working.

All I have understood so far are the simplistic threads and from what I have read you can't actually control them once they have started.


Code:
import threading
import requests

function_test_function():
  requests.get('http://mywebsite.com/returnvalue.php')


getLed_thread = threading.Thread(target=function_test_function)
getLed_thread.start()

This part works well but I just need to get over this hurdle to move on and I don't quite understand the tutorials I have been seeing out there.
 
Keep the reference to getLed_thread around somewhere you can access it from the button.
The simplest, but possibly least robust way would be to use threading.Thread.is_alive(). to see if the thread is still alive.
Or you could use locks that the thread holds, and your button checks, which would allow you to only hold the lock during part of your threads execution.
 
I'm starting with the simplistic method first since I understand this method for now.
(I'm very new to python)

I added this code to the part of my program that checks the button press. Upon press I thought I would run this check to see if the thread is running.
Code:
if (getLed_thread.is_alive() == True):
  print ('thread is running)

I'm getting an error on the IF statement line saying
"NameError: name 'getLed_thread' is not defined"

I wanted to see if this error was because there was no thread running (since when the program starts there has not been any button press and therefore no thread ever defined).
I did this by starting a thread once at startup. This seems to be the case. Once the thread ran once then I was able to determine true or false on the thread from that point on.

Any thoughts on why this may happen and how I can get around it?

Also, I'm going to have two threads that need to run as part of this project. Is there a way I can specify them ahead of time? Maybe that will help me get around this problem.
 
Last edited:
Okay I got around one of the problems by placing the following line before the main program runs:
getLed_thread = threading.Thread(target=function_test_function)

This way the thread exists when I go to start() it when the button is pressed. But I can only start() once. The second time I hit the button I get an error saying you can't start a thread more than once.

I tried run() but that yeilds the same result. I tried join() but I need to start() before I can join and I don't want to start until the button is pressed the first time.

I found a work around to my problem. I am currently using arguments.
getLed_thread = threading.Thread(target=function_test_function, args=('first run',) )
getLed_thread.start()

Then when the button is pressed I do this:
getLed_thread = threading.Thread(target=function_test_function, args=('all runs',) )
getLed_thread.start()

I added some code to the function_test_function(runValue) that checks to see what the argument is. If it's "all runs" then it executes the code. if it's not it ignores it. So when the device starts up it will "ignore" the first call to the thread. Then when the button is pressed "all runs" is passed as an argument and the code I wrote executes the lookup to my website.

I'm not exactly proud of this method but it has helped me understand how to use arguments. But I want to figure out how to do this the right way!
 
Last edited:
try something like:
#earlier in your code
getLed_thread = None #define the variable, so you don't get a Name error when checking the variable
#elsewhere
if getLed_thread is not None and getLed_thread.is_alive():
pass#allready running
else:
pass#run a new thread
 
ohhhh the name error is because the variable isn't defined....
you know, I caught that error on a different variable I was defining but I didn't put two and two together for this one.
I'll give it a shot.
 
Back
Top