Use semaphores to mutually exclude competing threads or control access to a resource. A semaphore is a built-in 4Test data type that can only be assigned a value once. The value must be an integer greater than zero. Once it is set, your code can get the semaphore's value, but cannot set it.
SEMAPHORE semA = 10 // Legal semA = 20 // Illegal - existing semaphore // cannot be reinitialized if (semA == [SEMAPHORE]2)... // Legal - note the typecast Print ("SemA has {semA} resources left.") // Legal SEMAPHORE semB = 0 // Illegal - must be greater than 0
To compare an integer to a semaphore variable, you must typecast from integer to semaphore using [SEMAPHORE].
To use a semaphore, you first declare and initialize a variable of type SEMAPHORE. Thereafter, 4Test controls the value of the semaphore variable. You can acquire the semaphore if it has a value greater than zero. When you have completed your semaphore-protected work, you release the semaphore. The Acquire function decrements the value of the semaphore by one and the Release function increments it by one. Thus, if you initialize the semaphore to 5, five threads can simultaneously execute semaphore-protected operations while a sixth thread has to wait until one of the five invokes the Release function for that semaphore.
The Acquire function either blocks the calling thread because the specified semaphore is zero, or "acquires" the semaphore by decrementing its value by one. Release checks for any threads blocked by the specified semaphore and unblocks the first blocked thread in the list. If no thread is blocked, Release "releases" the semaphore by incrementing its value by one so that the next invocation of Acquire succeeds, which means it does not block.
void Acquire(SEMAPHORE semA)Where semA s the semaphore variable to acquire.
void Release(SEMAPHORE semA)Where semA s the semaphore variable to release.
If more than one thread was suspended by a call to Acquire, the threads are released in the order in which they were suspended.
A semaphore that is assigned an initial value of 1 is called a binary semaphore, because it can only take on the values 0 or 1. A semaphore that is assigned an initial value of greater than one is called a counting semaphore because it is used to count a number of protected resources.
SEMAPHORE DBUsers = 3 ... Acquire (DBUsers) access database Release (DBUsers)The declaration of the semaphore is global; each thread contains the code to acquire and release the semaphore. The initial value of three ensures that no more than three threads will ever be executing the database access code simultaneously.