Home > Mobile >  Understanding Semaphores in C#
Understanding Semaphores in C#

Time:12-24

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

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.

  • Related