SOfanatic
SOfanatic

Reputation: 5573

semaphores C# Object synchronization method was called from an unsynchronized block of code

I was trying to follow a piece of pseudo-code having to do with Semaphores and when I translated the code to C# I'm getting the error in the title.

After some research, the error is happening because I'm calling cust_ready.ReleaseMutex() without calling cust_ready.WaitOne() within the same thread. The problem is that this is exactly what the pseudo-code is doing so I'm not sure how to resolve this?

cust_ready.WaitOne() is called but in a separate thread, below is the pseudo code in question:

Thread1:

wait(mutex2);

enqueue(custnr);

signal(cust_ready);

signal(mutex2);

Thread2:

wait(cust_ready);

wait(mutex2);

dequeuel(b_cust);

signal(mutex2);

and this is my C# code:

Thread1:

mutex2.WaitOne();

customerQueue.Enqueue(custnr);

cust_ready.ReleaseMutex();

mutex2.ReleaseMutex();

Thread2:

cust_ready.WaitOne();

mutex2.WaitOne();

var exists = customerQueue.TryDequeue(out var b_cust);

mutex2.ReleaseMutex();

Upvotes: 1

Views: 178

Answers (2)

tmaj
tmaj

Reputation: 34997

I'd recommend using ConcurrentQueue Class.

All public and protected members of ConcurrentQueue are thread-safe and may be used concurrently from multiple threads.

Upvotes: 0

Lukasz Szczygielek
Lukasz Szczygielek

Reputation: 3110

Mutex is an object to synchronize access to resources and you use it to protect customerQueue. On the other hand, mutex is not designed to signal something. To signal you can use AutoResetEvent as cust_ready.

Thread1

mutex2.WaitOne();
customerQueue.Enqueue(custnr);
cust_ready.Set();
mutex2.ReleaseMutex();

Thread2

cust_ready.WaitOne();
mutex2.WaitOne();
var exists = customerQueue.TryDequeue(out var b_cust);
mutex2.ReleaseMutex();

Similar topic Thread signaling basics

AutoResetEvent documentation - remarks section mentions other objects which can be used to signal between threads.

Upvotes: 1

Related Questions