1. Global Variable Safety with Multi-tasking
- Posted by cp Aug 13, 2012
- 1623 views
What technique (if any) do I need to use to ensure safety when using global variables with real-time tasks?
For example two real-time tasks need to access a global sequence. Task A will read from configuration file every few minutes and may update (add or remove) some elements in the global sequence. Task B will loop thru the elements in the global sequence performing some operations.
If task B yields to task A and task A changes the number of elements in the sequence, when execution returns to task B that could cause a problem with the "for" loop count?
Do I need to ensure that task B only yields after the for loop is complete to be safe? something like:
procedure task_B() while 1 for i = 1 to length(seqGlobal) do DoSomeStuff(seqGlobal[i]) end for task_yield() end while end procedure
Or are their other options which will allow yield more often within the for loop?
thanks, Casey
2. Re: Global Variable Safety with Multi-tasking
- Posted by mattlewis (admin) Aug 14, 2012
- 1540 views
What technique (if any) do I need to use to ensure safety when using global variables with real-time tasks?
For example two real-time tasks need to access a global sequence. Task A will read from configuration file every few minutes and may update (add or remove) some elements in the global sequence. Task B will loop thru the elements in the global sequence performing some operations.
If task B yields to task A and task A changes the number of elements in the sequence, when execution returns to task B that could cause a problem with the "for" loop count?
Do I need to ensure that task B only yields after the for loop is complete to be safe?
If you're going to use a for loop, then yes. The upper bound is calculated when the loop is started, so it wouldn't notice the change in the sequence. Alternatively, you could use something like a while loop, though that would be more complicated, because you'd have to be able to know if your index variable needs to be incremented or decremented depending on how the sequence changed.
It's hard to give more detailed advice without knowing more about what exactly you're trying to do.
Matt
3. Re: Global Variable Safety with Multi-tasking
- Posted by EUWX Aug 14, 2012
- 1514 views
The solution for this kind of problem has already been established in the network model,where a variable or an element of a database is locked. If you want to use a global variable sequence in a task that is likely to be dynamically changed by another task, a good solution would be to look ahead at one or two elements (depending upon the likelihood of them being changed,) and use the appropriate one for your program.
Let us say, your loop is working with the 4th element of the sequence.
Instead of just picking up the fourth element, you picking it up from the stored one when you were doing the 3rd element, compare with the current, do a condition decision which one you will use and at the same time time you also store the value of the 5th and 6th element.
It will all depend upon what the interfering task is likely to do to the elements of a sequence.
Just my two pence worth.
4. Re: Global Variable Safety with Multi-tasking
- Posted by ghaberek (admin) Aug 15, 2012
- 1458 views
It sounds like you need to use a queue. Each task should be adding and removing objects to/from the queue and working on a local variable. This is a much safer way to prevent them from stomping all over each other.
sequence queue = {} procedure enqueue( object x ) -- add an object into the queue queue = append( queue, x ) end procedure function dequeue() -- (assume we've checked length(queue) elsewhere) -- pull the first object from the queue object x = queue[1] -- remove this object from the queue queue = queue[2..$] -- return the object return x end function procedure task_1() while doing_stuff do -- do stuff and queue an item object x = some_function() enqueue( x ) task_yield() end while end procedure procedure task_2() while 1 do -- loop forever while length( queue ) = 0 do -- wait until we have something to work on task_yield() end while -- get the next object object x = dequeue() -- do something with this object task_yield() end while end procedure
-Greg
5. Re: Global Variable Safety with Multi-tasking
- Posted by mattlewis (admin) Aug 15, 2012
- 1449 views
It sounds like you need to use a queue. Each task should be adding and removing objects to/from the queue and working on a local variable. This is a much safer way to prevent them from stomping all over each other.
For such a task, you might look at std/stack.e. In particular, use a FIFO stack.
Matt
6. Re: Global Variable Safety with Multi-tasking
- Posted by casey Aug 15, 2012
- 1401 views
It sounds like you need to use a queue. Each task should be adding and removing objects to/from the queue and working on a local variable. This is a much safer way to prevent them from stomping all over each other.
For such a task, you might look at std/stack.e. In particular, use a FIFO stack.
Matt
Thanks for the replies. Both the while loop instead of for loop and the queue technique should both work for me.
thanks again,
Casey