Comments
Loading Dream Comments...
You must be logged in to write a comment - Log In
ArtistTwo beautiful purple-haired women wearing a long purple velvet ankle-length dress with flouncy sleeves and purple suede high heels, are waiting at two bus stops.
Suppose we want to wait until one of several events occurs. In MS-Windows we would use rv = ::WaitForMultipleEvents(eventlist); in RSX we would use WT$LOR (wait for logical OR of events), i.e. any. Let's take a practical example -- an RS232 terminal program. Our main process waits for either a key to be typed on the keyboard, or a character to arrive in the UART buffer. It then branches two ways: if a key was pressed, it sends it to the RS232 transmit buffer, whereas if a character was received it sends it to the VDU screen. Clearly this is really two threads, two orthogonal control paths, so we would use two wait statements (one for the keyboard input and one for the RS232 input). There's no need to multiplex them and confuse the logic if the underlying platform supports multithreading. So we would code as follows :
KbdThread <:: {* running : ; // Loop round while running
?kbd; // Wait for a keypress
transmit <:: kbd; // Transmit the character
*}; // And loop round again
ReceiveThread <:: {* running : ; // Loop round while running
?receive; // Wait for a character
ttyout( receive ); // Display it on the screen
*}; // And loop round again
We have added a "running" boolean, in order to prevent our loops becoming infinite. When we wish to exit this terminal client, we just set
running <:: 0; // stop run
Now we declare our two active threads :
{! KbdThread; ReceiveThread !}; // using thread brackets "{!" and "!}"
This logic looks clearer than having a single thread wait for multiple events. However, if we really wanted to do so, we could have two threads which each wait for one of the events, and when it occurs they each set an event flag (itself a Buf). Our main thread then waits on that event flag :
?Buf
which has the same effect as waiting on the occurrence of any one of the original event flags.
Summary :
To wait for an event flag, we wait for a Buf to become non-empty : "?Buf"
To set an event flag, we write (or insert) to that Buf : "Buf <:: 1"
To clear an event flag, we write NULL to that buf (or extract all its contents) : "Buf <:: ()"
Threads are cheap in ::SHE+ILA::, so no worries :)