1

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!

Brett
  • 11,637
  • 34
  • 127
  • 213
  • 1
    Look at which other pieces of code use the same semaphore. Semaphores are used for synchronization and signalling. I expect the DataReceived handler is what signals the semaphore. – Luaan Dec 23 '21 at 16:49
  • I'm assuming `_transactionsSession.StartSession();` acquires the Semaphore 100 times. Because the Semaphore can be acquired a maximum of 100 times, this means that the `_transactionReceived.WaitOne(10000);` blocks, because there are no free requests for the Semaphore to grant. The transactions stream is "functioning" when it releases the Semaphore once -- this doesn't mean that the operation is complete, just that one 100th of something has finished, most likely – canton7 Dec 23 '21 at 16:55
  • Helpful answer on explanation of initialCount: https://stackoverflow.com/a/9363524/255259 – dugas Dec 23 '21 at 17:38

2 Answers2

2

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.

Johnathan Barclay
  • 18,599
  • 1
  • 22
  • 35
2

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();
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305