Class
Semaphore
Description
Used to control access to resources in a multithreaded environment.
Methods
Name |
Parameters |
Returns |
Shared |
---|---|---|---|
resourceCount As Integer = 1 |
|||
Method descriptions
Semaphore.Constructor
Constructor(resourceCount As Integer = 1)
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
The Semaphore has a constructor that takes the initial count of the number of resources the Semaphore is protecting as an optional parameter. This defaults to 1. If you need to manage access to a single resource, you can instead use a CriticalSection.
Semaphore.Release
Release
Call Release to give a locked resource back to the Semaphore. You must call Release when you are finished using a locked resource in order to make it available to other requests.
Semaphore.Signal
Signal
Call Signal to obtain a lock on a resource. Once you are done with the shared resource, the thread should call Release to increment the internal counter.
Every time thread calls Signal, the Semaphore decrements the counter. If the counter is less than zero, it suspends the thread.
When you obtain a lock, you can use the resource without fear that another thread will try to use it simultaneously. If the call succeeds, this function returns immediately and you code continues to execute. If the lock is not available, then the thread that called this method will wait until the lock becomes available. When the call returns, you will have the lock, but you may have to wait until the lock becomes available. When you are finished using the resource, call the Release method to give it back to the Semaphore.
Semaphore.TrySignal
TrySignal As Boolean
This is a more friendly version of the Signal method that gives you a sneak-peek to determine whether there is a lock available.
If there is a lock available, you are granted the lock and TrySignal returns True. When you are finished with the resource, call Release to give it back to the Semaphore. If the lock is not available, you do not wait for it. Instead, TrySignal returns False to let you know. Do not attempt to use the resource after it returns False because you are likely to collide with another thread.
This example tests whether the lock is available before trying to use the resource.
' Want to make sure that only the right thread
' gets in here. One at a time!
If mLock.TrySignal Then
' Now that we're here, we can change the resource
SharedResource.Value = value
AccessText.Text = id.ToString
' And now that we've done something with the
' resource, we want to release our lock on it
mLock.Release
End If
Semaphore.Type
Type As Types
Indicates the type of the Semaphore, Cooperative or preemptive. Cooperative is the default.
Carefully read the Preemptive Threads notes before using them.
Notes
A Semaphore is an object that can be used to coordinate access to a shared resource.
To acquire the ownership of a Semaphore, a thread calls the Signal or TrySignal methods. If the Semaphore isn't owned, the thread acquires ownership, which means you have a lock on it. Otherwise the thread is forced to wait until the Semaphore is released via the Release method by the owning thread.
Every time you successfully obtain an ownership lock on the resource, the Semaphore will decrement its internal count of available resources. When there are no more resources, threads that request ownership locks will begin to block and wait for resources. This is why you can specify the initial count of resources - to give you more control over the behavior of the Semaphore.
The Semaphore class is different from the CriticalSection and Mutex classes in this way: calling Signal in the same thread will cause the counter to decrement. If you call Signal recursively, you will cause the application to hang.
Sample code
This example uses a Semaphore to ensure that only one thread at a time writes to a file.
Add a public property to the App class:
FileAccess As Semaphore
And in the Opening event handler, initialize it:
' Allow only a single thread to access the file at a time
FileAccess = New Semaphore(1)
In the thread, check the FileAccess Semaphore to see if you can write to the file:
' This will Suspend this thread if another has the lock
' When it is released, this thread will continue to run
App.FileAccess.Signal
' Now you can open the file for writing
WriteDataToFile ' Call your code here
' When you are finished, release the semaphore
App.FileAccess.Release
Compatibility
All project types on all supported operating systems.
See also
Object parent class; CriticalSection, Mutex, Thread classes.