AutoResetEvent as a Lock replacement in C#?
Asked Answered
S

2

13

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_

Sackbut answered 24/6, 2013 at 11:4 Comment(3)
SO does have similar question: #1717694Dalpe
@Dalpe heh , all 3 terms are in the general composition ( monitor.enter vs lock , autoreset vs waithandle....) but yeah it's similar. however please notice that AutoResetEvent /waithdnales are not shared between processes. the writer confused with Mutex. anyway he is wrong. ( about that).Sackbut
@Dalpe also the most rated answer talks about differences when there is a set command ( weather if thread is waiting or not).Sackbut
S
21

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.

Sonde answered 24/6, 2013 at 11:24 Comment(4)
fairness - Does this means that if threads : 1,5,7 ( in that order) came to the lock region , the lock will (when released) will be fair and it will released to threads 1-->5-->7 ? ( while waitHandles can do : 1-->1-->1 - because the thread may has a higher process/thread priority ?)Sackbut
There are a few quirks related to APCs so this is not strictly the case. But yes, that's the normal order in which threads acquire a lock when the sync object promises fairness.Sonde
Hans I also read somewhere that : if there is no other threads that want the lock - the kernel resource( or something like that) is not even taken....can you reference me please to the right term ?Sackbut
It is an implementation detail of the Monitor class. It takes a cheap internal lock first to find out if the lock is contended. And only takes the expensive kernel one when it is. Nice optimization. No idea what kind of search terms will find details like this, you can read the SSCLI20 source code to see how an AwareLock works. Or click the Ask Question button.Sonde
B
2

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.

Bersagliere answered 24/6, 2013 at 11:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.