task_yield
Definition: | task_yield() |
Description: | Yield control to the scheduler. The scheduler can then choose another task to run, or perhaps let the current task continue running. |
pwa/p2js: | Not supported. |
Comments: |
Tasks should call task_yield() periodically so other that tasks have a chance to run. Only when task_yield() is called, is there a way for the scheduler to take back control from a task. This is known as cooperative multitasking. A task can have calls to task_yield() in many different places in its code, and at any depth of subroutine call. Note however there are significant restrictions for c_func/call_func/call_back/delete_routine/type-check, see technicalia. The scheduler uses the current value of {min, max} or the current number of consecutive runs remaining, in determining when to return to the current task. When control returns, execution continues with the statement that follows task_yield(). The call-stack and all private variables remain as they were when task_yield() was called. Global and local variables may have changed, due to the execution of other tasks. Tasks should try to call task_yield() often enough to avoid causing real-time tasks to miss their time window, and to avoid blocking time-shared tasks for an excessive period of time. On the other hand, there is a bit of overhead in calling task_yield(), and this overhead is slightly larger when an actual switch to a different task takes place. A task should avoid calling task_yield() when it is in the middle of a delicate operation that requires exclusive access to some data. Otherwise a race-condition could occur, where one task might interfere with an operation being carried out by another task. In some cases a task might need to mark some data as "locked" or "unlocked" in order to prevent this possibility. With cooperative multitasking, these concurrency issues are much less of a problem than with preemptive multithreading. |
Example 1: |
-- this is how the main thread might wait for all tasks to complete terminate_application = 1 -- tell threads to start shutting down, if appropriate while active_tasks>0 do -- (active_tasks is a manually maintained counter) task_yield() sleep(0.1) -- (recommended if any real-time tasks are in use) end while abort(0) |
Example 2: |
-- an alternative to the above: main_task_id = task_self() task_suspend(main_task_id) task_yield() -- (nb: if no other task invokes task_schedule(main_task_id), control never returns) |
Example Programs | Both demo\rosetta\Generator_Exponential.exw and demo\rosetta\Same_Fringe.exw use task_yeild to implement a routine that can suspend itself mid-execution and later be resumed to obtain the next value, as many times as desired. |
Implementation: | See builtins\VM\pTask.e (an autoinclude) for details of the actual implementation. |
See Also: |
task_create,
task_schedule,
task_suspend,
task_self |
