ricardo.santos
Posts: 43
Joined: Thu Jan 18, 2018 12:18 pm

Continuasly run a function and in parallel control other functions

Sat Mar 03, 2018 8:46 pm

Hi

I need to built a pythonfile.py that starts to do a task (monitor at all time a serial port)
And when a certain condition is true(receive a certain byte in serial) start/stop certain functions that I already have.

But is important that the task of reading the serial port is always running and never stops.

So imagine that I have

Readserial()
While true:
Read the serial port (I know how to do this)

If readbyte = 0x65: #(for example)
Stop Function1() #(but at the same time Readserial() should continue monitoring serial port)

If read byte = 0xFF: #example
start Function2() #(again readSerial() should continue to run)

Function1()
Do something

Function2()
Do something


What is my best solution for this
Threading?
callback?
Other?

If someone give a possible help in the general structure I would appreciate since I'm an not an expert at programming
thanks

User avatar
OutoftheBOTS
Posts: 711
Joined: Tue Aug 01, 2017 10:06 am

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 10:05 am

I think threading is probably the best.

Will you need to do both Function1() and Function2() at the same time or is it ok I 1 function waits till the other is finished??

If you don't need the 2 fuctions to run at the same time and just the serial read to run in parallel you can do this.

Code: Select all

#Have 2 global flags : 
fuction1_flag = False
fuction2_ flag = False

def read_serial ():
 while True:
   #code to read serial
    global fuction1_flag
    global fuction2_flag
    if readbyte = 0x65:fuction1_flag = True
    if read byte = 0xFF:fuction2_flag = True
  
def fuction1():
  global fuction1_flag
  fuction1_flag = False
  #code here
  
def fuction2():
  global fuction2_flag
  fuction2_flag = False
  #code here

thread.start_new_thread( read_serial )  
while True:
  if fuction1_flag : fuction1()
  if fuction2_flag : fuction2()
Last edited by OutoftheBOTS on Mon Mar 05, 2018 6:05 am, edited 1 time in total.

ricardo.santos
Posts: 43
Joined: Thu Jan 18, 2018 12:18 pm

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 10:36 am

That's great thanks
What if I want to pause Function1() while is running and flag becomes false
It's not doing that know right.?
Is there a way to put the function like in a queue and pause or stop then if the flags become false?

User avatar
croston
Posts: 703
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
Contact: Website

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 10:58 am

I think that Python's asyncio mechanism is useful in this type of situation.
Some reading:
https://www.blog.pythonlibrary.org/2016 ... o-asyncio/
https://pymotw.com/3/asyncio/
http://pyserial-asyncio.readthedocs.io/en/latest/

ricardo.santos
Posts: 43
Joined: Thu Jan 18, 2018 12:18 pm

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 7:43 pm

OutoftheBOTS wrote:
Sun Mar 04, 2018 10:05 am
I think threading is probably the best.

Will you need to do both Function1() and Function2() at the same time or is it ok I 1 function waits till the other is finished??

If you don't need the 2 fuctions to run at the same time and just the serial read to run in parallel you can do this.

Code: Select all

#Have 2 global flags : 
fuction1_flag = False
fuction2_ flag = False

def read_serial ():
 #code to read serial
  global fuction1_flag
  global fuction2_flag
  if readbyte = 0x65:fuction1_flag = True
  if read byte = 0xFF:fuction2_flag = True
  
def fuction1():
  global fuction1_flag
  fuction1_flag = False
  #code here
  
def fuction2():
  global fuction2_flag
  fuction2_flag = False
  #code here

thread.start_new_thread( read_serial )  
while True:
  if fuction1_flag : fuction1()
  if fuction2_flag : fuction2()
Whoud the class threading.Event be helpful? Or queue class is preferable?
https://docs.python.org/3.5/library/thre...Event.wait

User avatar
OutoftheBOTS
Posts: 711
Joined: Tue Aug 01, 2017 10:06 am

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 9:31 pm

What if I want to pause Function1() while is running and flag becomes false
It's not doing that know right.?
Is there a way to put the function like in a queue and pause or stop then if the flags become false?
There is a large number of ways to do threading depending upon what you want to achieve and there is a number of pit falls to threading as well.

The program that I posted is very simple for a beginner to understand. It has the main program and just 1 extra thread (serial_read). The functions are called from the main program and only 1 function can run at a time so the other can't start till the first 1 finishes, i.e the fuctions are called in a synchronized manner and are blocking.

You may want your program to be able to run both functions at the same time. i.e if the byte is received to start fuction1 is received while fuction2 is running then execute fuction1 at that time rather than wait till function2 is finished. To do this you will need to have 2 more threads where fuction1 and fuction2 also run on threads. This can have some traps like fuction1 can interfere with fuciton2 because they trying to access the same data or resources also if you write a program to start a fuction1 on a thread when a byte is received if this byte is received and fuction1 starts a new thread then the byte is received again before fuction1 thread is finished it will start another thread of another function1 so that you will have 2 threads running fuction1.

As for pausing the calling of 1 of the functions in my above program this can also be done with a flag.

Code: Select all

#Have 2 global flags : 
fuction1_flag = False
fuction2_ flag = False


def read_serial ():
 while True:
   #code to read serial
    global fuction1_flag
    global fuction2_flag
    if readbyte = 0x65:fuction1_flag = True
    if read byte = 0xFF:fuction2_flag = True
  
def fuction1():
  global fuction1_flag
  fuction1_flag = False
  #code here
  
def fuction2():
  global fuction2_flag
  fuction2_flag = False
  #code here

thread.start_new_thread( read_serial )  
not_paused_flag = True
  
while True:
  if fuction1_flag and not_paused_flag: fuction1()
  if fuction2_flag and not_paused_flag: fuction2()
Last edited by OutoftheBOTS on Mon Mar 05, 2018 6:04 am, edited 1 time in total.

User avatar
OutoftheBOTS
Posts: 711
Joined: Tue Aug 01, 2017 10:06 am

Re: Continuasly run a function and in parallel control other functions

Sun Mar 04, 2018 10:18 pm

This version runs the read serial in main loop and the 2 functions on threads so it will be possible to have both fuction1 and fuction2 running at the same time but not possible to have multiple threads of same function.

Code: Select all

#Have 2 global flags : 
fuction1_flag = False
fuction2_ flag = False

  
def fuction1():
  global fuction1_flag
  while True:
    if fuction1_flag :
      fuction1_flag = False
      #code here
  
def fuction2():
  global fuction2_flag
  while True:
    if fuction2_flag :
      fuction2_flag = False
      #code here

thread.start_new_thread( fuction1 )
thread.start_new_thread( fuction2 )  
 
while True:
  #code to read serial
  if readbyte = 0x65:fuction1_flag = True
  if read byte = 0xFF:fuction2_flag = True

ricardo.santos
Posts: 43
Joined: Thu Jan 18, 2018 12:18 pm

Re: Continuasly run a function and in parallel control other functions

Mon Mar 05, 2018 9:56 am

Thanks a lot OutoftheBOTS, you were very helpful

I will try to implement your advices.

Return to “Python”