|
Threads |
Top Previous Next |
|
Diamond supports multi-threaded tasks. In fact, Diamond starts every task by invoking its main function as a thread. A task may be stopped using thread_stop.
Tasks and threads dynamically create new execution threads by passing a function pointer and an amount of workspace (stack) to a library function. The library function returns and the creating thread continues to execute while the new execution thread starts executing the code of the function concurrently. The new thread runs in the same context as its creator; they share their static, extern and heap memory areas. The only private storage available to the new thread is its workspace. This is similar to the execution threads of Windows and some flavours of Unix. Each thread has its own stack but shares the rest of its data with all the other threads in the same task.
The parent thread has no direct control over its offspring, which continues to execute until it terminates itself by returning from the function that was invoked, or by calling thread_stop. Note that when a thread 'returns' it stops; there is no actual return from the function.
Threads are most commonly created during the initialisation phase of a task and are almost always infinite loops.
Semaphore functions in the run-time library can be used to prevent threads that share data from interfering with each other. Alternatively, internal channels declared as program variables can be used to synchronize the threads' operations and transmit data between them by passing messages. Diamond provides a CHAN data type that can be used to declare channel variables.
Of course, like any other software construct, threads may be used in contexts other than those in which they are formally necessary. Indeed, many problems in simulation, real-time control and other areas map well onto a multi-threaded algorithm, although they do not strictly require to be executed in this way. |