Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoResetEvent as a Lock replacement in C#?

I was wondering: Locking allows only 1 thread to enter a code region

And wait handles is for signaling : :

Signaling is when one thread waits until it receives notification from another.

So I thought to myself , can this be used to replace a lock ?

something like :

Thread number 1 --please enter ( autoreset --> autlock)
dowork...
finish work...
set signal  to invite the next thread

So I wrote this :

/*1*/   static EventWaitHandle _waitHandle = new AutoResetEvent(true);
/*2*/   
/*3*/   volatile int i = 0;
/*4*/   void Main()
/*5*/   {
/*6*/   
/*7*/       for (int k = 0; k < 10; k++)
/*8*/       {
/*9*/           var g = i;
/*10*/           Interlocked.Increment(ref i);
/*11*/           new Thread(() = > DoWork(g)).Start();
/*12*/   
/*13*/       }
/*14*/   
/*15*/       Console.ReadLine();
/*16*/   }
/*17*/   
/*18*/   
/*19*/   void DoWork(object o)
/*20*/   {
/*21*/       _waitHandle.WaitOne();
/*22*/       Thread.Sleep(10);
/*23*/       Console.WriteLine((int) o + "Working...");
/*24*/       _waitHandle.Set();
/*25*/   
/*26*/   }

as you can see : lines #21 , #24 are the replacement for the lock.

Question :

  • Is it a valid replacement ? ( not that i will replace lock , but want to know about usages scenarios)
  • When should I use each ?

Thank you.

strange but SO does not contain a question regarding _lock vs EventWaitHandle_

like image 482
Royi Namir Avatar asked Jun 24 '13 11:06

Royi Namir


People also ask

What is AutoResetEvent?

AutoResetEvent remains signaled until a single waiting thread is released, and then automatically returns to the non-signaled state. If no threads are waiting, the state remains signaled indefinitely. If a thread calls WaitOne while the AutoResetEvent is in the signaled state, the thread does not block.

Why do we use lock statement in C?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

What is locks and process concept in C#?

C# Lock keyword ensures that one thread is executing a piece of code at one time. The lock keyword ensures that one thread does not enter a critical section of code while another thread is in that critical section. Lock is a keyword shortcut for acquiring a lock for the piece of code for only one thread.


2 Answers

Do not go there. An important property of a lock is that it provides fairness. In other words, a reasonable guarantee that threads that contend for the lock get a guarantee that they can eventually acquire it. The Monitor class provides such a guarantee, implemented by a wait queue in the CLR. And Mutex and Semaphore provide such a guarantee, implemented by the operating system.

WaitHandles do not provide such a guarantee. Which is very detrimental if the lock is contended, the same thread can acquire it repeatedly and other threads can starve forever.

Use an appropriate synchronization object for locks. Wait handles should only be used for signaling.

like image 190
Hans Passant Avatar answered Oct 23 '22 16:10

Hans Passant


It is possible, but it is much slower than lock() and much harder to maintain.

By the way, you should never read a value directly when using Interlocked-methods to maintain it.

Your code should look like this:

var g = Interlocked.Increment(ref i);

Then g will contain the incremented value rather than an abitrary previous value.

like image 1
Casperah Avatar answered Oct 23 '22 15:10

Casperah