Threading¶
Unicon threading¶
Unicon supports concurrent processing, tasks, and threads.
Threading is documented in Unicon Technical Report 14, by Jafar Al-Gharaibeh and Clinton Jeffery.
http://unicon.org/utr/utr14.pdf
Unicon threads build on Unicon Co-Expressions. Normally co-expressions are synchronous, thread co-expressions are asynchronous.
Thread creation¶
Unicon threads can be created with the reserved word thread or the
function spawn. The spawn()
function turns a previously created
synchronous co-expression into an asynchronous threaded co-expression. The
thread
reserved word creates a thread and starts it running.
thread expr
is equivalent to:
T := spawn(create expr))
@T
Both thread
and spawn()
return a reference to the new thread.
Hello, threads¶
This example creates running threads, but there is no synchronization with main. The main procedure may end, terminating the run, before the threads have a chance to complete, (or it may not, due to the nature of asynchronous threading).
#
# threading.icn, Hello, threads, not sychronized
#
procedure main()
every t := !10 do thread write("Hello, world; I am thread: ", t)
write("main: complete")
end
Initial test:
Hello, world; I am thread: 1
Hello, world; I am thread: 2
Hello, world; I am thread: 3
Hello, world; I am thread: 4
Hello, world; I am thread: 5
Hello, world; I am thread: 6
Hello, world; I am thread: 7
Hello, world; I am thread: 8
Hello, world; I am thread: 9
main: complete
That sample run may or may not allow all ten threads to finish before the main program completes and returns to the operating system.
This next example uses wait to ensure that all the threads complete before main terminates.
#
# threading-synch.icn, Hello, threads, sychronized with wait
#
procedure main()
Lt := []
every t := !10 do put(Lt, thread write("Hello, world; I am thread: ", t))
every wait(!Lt)
write("main: complete")
end
Waited run:
Hello, world; I am thread: 1
Hello, world; I am thread: 2
Hello, world; I am thread: 3
Hello, world; I am thread: 4
Hello, world; I am thread: 5
Hello, world; I am thread: 6
Hello, world; I am thread: 7
Hello, world; I am thread: 8
Hello, world; I am thread: 9
Hello, world; I am thread: 10
main: complete
Using wait is the recommended way of dealing with thread execution to ensure the threads are given a chance to complete. Keeping a list structure of thread references is a handy and reliable way of managing this idiom.
Attention
Threaded programming is hard. It adds an extra dimension to processing that requires special care and attention to detail. Most operations in a computer program are multiple step, non atomic operations. Even something as simple as incrementing a variable is split at the machine level as fetch, increment, store. Threads may enter the operation at any point in time, and two competing threads may conflict between the fetching and incrementing steps, causing erroneous results. Guards must be put in place to ensure that every section of code is allowed to complete each step before another thread starts in on the operation. Unicon has kept this in mind and critical section management is part and parcel of safe, reliable thread programming.
Multi-tasking¶
Clinton Jeffery has enhanced the virtual machine to allow multi-tasking. Multiple programs can be loaded into the VM and invoked as Unicon Co-Expressionss. See load.
The poor person’s expensive uval
compile at runtime function uses load
to load a different task to perform the equivalent of an eval
function.
Not perfect, but satisfactory for many applications that need to evaluate
arbitrary Unicon programs or program fragments. The unitest testing
framework uses uval
to compile and test arbitrary code fragments from text
source.
The multi-tasking features started life as a method to allow execution
monitoring and control. Comes in handy for many things, and will likely play
a large part of any future evaluate at runtime form of an eval
function.
Index | Next: Features | Previous: Networking