i’m using threading module to execute functions asynchronous.
all functions are wrapped in a while True loop for continous execution.
my issue is that functions are triggered from the while True loop, and executing again even if the previous execution is still in progress.
For example the while True is 0.5 sec and the function needs 4-5 seconds to be done.
How can i achieve something like this ? (Not re-execute the thread.start function if the previous .start() still running ?)
Hello, yes of course.
Below are sample functions and modbus_pulse function taking 4 seconds.
All is executed with threading.start() and everything wrapped in infinite loop.
what i’m seeking is : not re-execute the modbus_pulse function if already there is an execution going on. (is actually executed every time from while True loop).
triggering like code below is executing new thread every time. Is there any way to check if running not to run again ? even if i used the check function is_alive, is executing new thread every time.
while True:
t1=threading.Thread(target=f1)
if t1.is_alive()==False:
t1.start()
t2=threading.Thread(target=f2)
if t2.is_alive()==False:
t2.start()
t1 is redefined each loop, you’ll need to create the threads outside of the loop, and then start them in each iteration, if they’re not running. Same for t2.
I’m not sure if threads are “reusable” like this, but there’s one way to find out… Try it and see what happens! (An exercise for the reader).
You could also read the threading module documentation carefully - but who has time for that?
For a more simple demo of why t1 is a different thread each iteration of the whole loop, try this:
def check(x):
x += 1
print(x)
while True:
x = 1
check(x)
this prints 2 forever
Vs.
def check(x):
x += 1
print(x)
x = 1
while True:
check(x)
This… Huh? Also prints 2… Forever. Weird right?
This happens because the int is copied into the check function, instead of being modified in place.
What happens if you use an object that is passed by reference into the function, for example a list?
These will perform their prints, then call threading.Thread(None) which doesn’t achieve much (it’ll create a thread with its group set to None, which is the default, and it has no target and therefore will do nothing).
I’m not sure what you expect the difference between these calls to be. One of the threads gets started, the other doesn’t. In theory, if they actually had targets, this would mean that the second one doesn’t actually execute, but the first one does; but I don’t understand your descriptions “one shot threaded” and “one shot”.
I’m not sure what is what yet, so i’ve been testing the difference between all functions of threading library. so: .start() and without .start(), is the same thing if you don’t want to create an object of threading and reuse it. those two lines are executing in a separate thread, not the main program thread.
My target was to execute separate functions continuously, in a separate thread. This is achieved by having a while True inside the function and thread it start only once.
the continuity of threads is just a preemptive fake and the switchinterval determines the frequency of preemption
so if the functions haven’t got anything to do with each other threading will be counterproductive
if you have lots of cores try processes: almost same interface and switching is done by the OS
In other words in python if the threads are compute bound python code threads are not helpful. But if you are doing I/O bound functions it will help. If the compute bound are doing the work by calling i to C extensions like numpy then you can see a speed up.
Hello everyone and many thanks for your contribution.
Let’s take a step backwards, so everyone understands the objective and then i’m willing to test any suggestion in real applications.
I have a modbus client code which read modbus values from field devices and writing modbus values to several devices. Modbus protocol on TCP originated from Serial protocol, so is based on request and answer from the requested device. For efficiency, parallel requests must be executed. The pulse feedback we need will be a modbus write command with value 0-1-0 for 3 seconds to simulate acceptance pulse. so a time.sleep(3) is needed.
At the same time, all other modbus reads and writes needs to executing in parallel. During this time.sleep(3) , everything else, all read/writes on modbus etc are stack. This is exactly what i’m trying to do : achieve a true multitasking behavior between the functions, just like a PLC that is able to execute all programs in a separate task , on a specific interval or trigger etc…
that’s why starting a new tread with target the function, it seems that is doing the job, but i’m open to try something else. I’m sure now is more clear. Thanks for any comments.