I am trying to understand a section of code written in C#:
static Semaphore _transactionReceived;
static TransactionsSession _transactionsSession;
static void StartTransactionsStream()
{
WriteNewLine("Starting transactions stream ...");
_transactionsSession = new TransactionsSession(AccountID);
_transactionReceived = new Semaphore(0, 100);
_transactionsSession.DataReceived = OnTransactionReceived;
_transactionsSession.StartSession();
bool success = _transactionReceived.WaitOne(10000);
if (success)
WriteNewLine("Good news!. Transactions stream is functioning.");
else
WriteNewLine("Bad news!. Transactions stream is not functioning.");
}
but I am having trouble understanding what is happening in the code cycle in regards to the Sempahore
class, particularly what the following lines are doing:
_transactionReceived = new Semaphore(0, 100);
and
_transactionReceived.WaitOne(10000)
is doing.
I have viewed and (re)viewed System.Threading.Semaphore
documentation, and I see that the contructor "Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries." But what does it mean when there are 0
entries?
Additionally, I see that the WaitOne(int32)
call "Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds." But again, what does WaitOne
that mean in the context of the code cycle?
Any pointers or general comments about how this is executing would be helpful. Many thanks!
CodePudding user response:
Explanation on semaphores
A Semaphore
is a synchronization object that allows a limited degree of parallelism in a code section.
For sake of simplicity, suppose you are instantiating a fresh new semaphore on a code block (no shared instance, global variable or other evil). Since multiple threads can execute the same piece of code at the same time, the semaphore guarantees only x
of them can execute the same block at the same time.
Think of a thread as a worker person. Not by coincidence, threads are often called worker threads.
But what does it mean when there are 0 entries?
The semaphore is in a red state, so no one can execute a particular code section until some thread unlocks the semaphore. You can create a GUI where multiple threads race for the same action, but by the press of a button you unlock the semaphore and allow one thread to go.
But again, what does WaitOne that mean in the context of the code cycle?
It means that one of the following happens:
- The semaphore is in a green state, i.e. has permits. The thread does not wait, the semaphore is decremented, the operation proceeds
- The semaphore is in a red state, i.e. has no permits available
- Either the
WaitOne
waits 10 seconds (10000ms) because no permit was available during that time - Or someone else unlocks the semaphore and the thread that invoked
WaitOne
is good to go
- Either the
About your code
There must be some other method that releases the semaphore but it is not shown in the example. In fact, you have a red semaphore where you wait, but apparently nobody to release it. I believe that one of these two lines hides a Semaphore.Release
method
_transactionsSession.DataReceived = OnTransactionReceived;
_transactionsSession.StartSession();
CodePudding user response:
But what does it mean when there are 0 entries?
Exactly that; the Semaphore
currently has no entries out of a maximum of 100.
If you had constructed the Semaphore
with new Semaphore(1, 100);
, then there would have been 1 entry, and another 99 remaining.
It would require a Semaphore.Release()
to have 100 remaining entries.
what does
WaitOne
that mean in the context of the code cycle?
If the Semaphore
has available entries i.e. the current number of entries is not 100, then it returns true
immediately.
Otherwise it blocks the current thread until an entry is available (proabably by another thread calling Semaphore.Release()
), at which point the method returns true
.
If you specify a int millisecondsTimeout
, that's the maximum amount of time the Semaphore
will block and wait for an entry to be released.
If that timeout is exceeded, the method returns false
.