سؤال

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_

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top