In sequential programming, I constantly encounter an obvious desire not to stop the program at the moment when the goal of individual tasks (processes) has periodic actions - for example, polling sensor values, or data transfer to the server according to the schedule, or input / output of a large amount of data. The simplest, of course, is to wait complete a periodic event and then, slowly, continue execute other tasks.
Code: Select all
while True:
do_ext_proc_before()
do_internal_proc()
sleep(5)
do_ext_proc_after()
Code: Select all
start = time()
set_timer(start,wait=5) # set schedule
set_timeout(start,wait_to=7) # set timeout
set_irq(alarm) # set interrupt
while True:
curTime = time()
do_ext_proc_before()
if timer(curTime) or timeout(curTime) or alarm:
# if all events crazy start simultaneously - reset all
start = time()
set_timer(start,wait=5) # set schedule
set_timeout(start,wait_to=7) # set timeout
set_irq(alarm) # set interrupt
do_internal_proc()
do_ext_proc_after()
Code: Select all
setTask(do_ext_proc_before())
setTask(do_internal_proc(),timer=5,timeout=7,alarm_handler=alarm)
setTask(do_ext_proc_after())
runTasks()
Peter Hinch (https://github.com/peterhinch/micropyth ... UTORIAL.md)
The simplest solution is to signal an event to an interested process. For this is the class Event (),
which contains several modules
- Event.Set (timeout = None,data = None) - set event occurrence (Event = True), for example,completion of data acquisition from sensors
Event.IsSet () - check if an event has occurred, returns True if set and False if not
Event.Wait () - wait for the event to occur, returns the reason for its completion - Done, Timeout, Cancel
Event.Data () - get data associated with this event
Event.Clear () - event completed (Event = False).
Keep in mind that Event.Clear () is advisable to do by only one process, if it does not contradict for a given algorithm. Otherwise, if several processes expect a Event.Set () event, it is assumed that Event.Clear () should be performed by one of the interested processes, only making sure that all interested processes responded to that event. What complicates decision-making logic when using Event-Class
while waiting for an event by multiple processes. This situation is resolved by setting a certain amount of Clear () event to occur.
- Barrier.Set (quantity = 1, timeout = None, data = None) - quantity = 1 identical Event.Set ()
Barrier.IsSet () - check if an event has occurred, returns True if set and False if not
Barrier.Wait () - wait for the event to occur, returns the reason for its completion - Done, Timeout, Cancel
Barrier.Data () - get data associated with this event
Barrier.qty - number of processes not yet completed
Barrier.Clear () - reset event (Event = False), executed by each process waiting for an event decreasing the Barrier.quantity counter by one until it is reset, only then the event will be reset
It does not keep track of which process has already responded, which may cause a problem re-respond to the event, if it is essential for a given algorithm. If instead of Barrier.quantity transfer the list of names of interested processes; such a conflict can be avoided. Also, in case of timeout or interruption of the event can be determined - which specific pending processes have not yet worked. All of the above applies to a situation where one or more processes are waiting for the occurrence of some event, or 'one-to-many' situations. This occurs when the process or processes do_ext_proc_after () by sequential programming would only be executed after do_internal_proc () is completed.
For the convenience of further understanding, we will extend the existing Event-Class and Barrier-Class to the new EEvent-Class and make it or the objects generated by him - global. Here 'creators' - the name or list of names of the process that initiates the occurrence of an event or blocks the resource and 'folowers' - the name or list of names of the processes awaiting the occurrence of an event or unlocking a resource
- EEvent.Set (creators, folowers, timeout = None, data = None) - as result returns True if it was possible to set an event or block a resource
EEvent.IsSet (procName) - procName - the name or ID of the process that ended
EEvent.Wait (procName)
EEvent.Clear (procName)
EEvent.Folowers () - as result returns a list of pending processes still queued for execution. Barrier.qty = len (EEvent.List ())
EEvent.Creators () - returns the list of processes that have already initiated the event
Code: Select all
def do_internal_proc():
...
EEvent.Set ('p_Creator',('p_Folwer1','p_Folwer2')) # exec 'p_Folwer1','p_Folwer2' after event is come in 'p_Creator'
...
def do_ext_proc_after1()
...
EEvent.Wait('p_Creator')
...
EEvent.Clear('p_Folwer1')
def do_ext_proc_after1()
...
EEvent.Wait('p_Creator')
...
EEvent.Clear('p_Folwer2')
Code: Select all
def do_ext_proc_before1()
...
EEvent.Set('p_Creator1','p_Folwer')
...
def do_ext_proc_before2()
...
EEvent.Set('p_Creator2','p_Folwer')
...
def do_internal_proc():
...
EEvent.Wait(('p_Creator1','p_Creator2'))
...
EEvent.Clear('p_Folwer')
Code: Select all
def do_internal_proc(): # lock activity all 'followers' in list
...
EEvent.Set ('p_Creator',('p_Folwer1','p_Folwer2')) # exec 'p_Folwer1','p_Folwer2' after event is come in 'p_Creator'
...
def do_ext_proc_after1()
...
EEvent.Wait('p_Creator') # waiting for recourse releale
if ( EEvent.Set ('p_Folwer1','p_Folwer2')): # lock resource 'p_Folower1' now is 'p_Creator'
...
else:
EEvent.Wait('p_Folower2') # continue waiting for recourse releale
...
EEvent.Clear('p_Folwer1') # releafe recourse
def do_ext_proc_after1()
...
EEvent.Wait('p_Creator')
if ( EEvent.Set ('p_Folwer2','p_Folwer1')): # lock resource 'p_Folower2' now is 'p_Creator'
...
else:
EEvent.Wait('p_Folower1') # continue waiting for recourse releale
...
EEvent.Clear('p_Folwer2') # releafe recourse
In conclusion, I want to say that sequential and asynchronous approaches have an equal right to exist and successfully implement the specified algorithms. Therefore, the use of a particular approach is determined by the priorities of the creator - what is more significant for him when implementing specified algorithms - transparency and readability, speed or amount of the resulting code.