Lock or semaphore, difference?

  • Thread starter Thread starter Carl
  • Start date Start date
C

Carl

Hi,

Are there any practial differences in execution between these to
alternatives? As far as I understand, they should execute exactly
the same, is that correct?

Alt1:
=======

private Semaphore _semaphoreTest = new Semaphore(1, 1, "SemaphoreTest");

try
{
_semaphoreTest.WaitOne();
sender.SendTest(Data, Stuff);
}
catch (Exception ex)
{
Log.Instance.LogAll(ex.Message + Environment.NewLine);
Log.Instance.LogAll(ex.StackTrace);
}
finally
{
_semaphoreTest.Release();
}

Alt2:
=======

private static Object _lock = new Object();

lock(_lock)
{
try
{
sender.SendTest(Data, Stuff);
}
catch (Exception ex)
{
Log.Instance.LogAll(ex.Message + Environment.NewLine);
Log.Instance.LogAll(ex.StackTrace);
}
}

Thanks in advace,

Carl
 
Carl said:
Are there any practial differences in execution between these to
alternatives? As far as I understand, they should execute exactly
the same, is that correct?
No.

Alt1:
=======

private Semaphore _semaphoreTest = new Semaphore(1, 1, "SemaphoreTest");
This creates a named kernel object. The semaphore you created takes up a
Win32 handle and is available to other processes. If other instances of your
application are running, they will get the same semaphore, so mutual
exclusion is guaranteed across processes.

You usually want to leave out the name to create a nameless semaphore that's
local to your process.
Alt2:
=======

private static Object _lock = new Object();
This creates a new managed object, which will happen to include the data
structures necessary for locking. This is not a kernel object and does not
consume a handle.

Functionally, from your application's point of view, these pieces of code
have the same effect, but the implementation is very different. Locks are
typically more efficient than the other synchronization primitives (but this
shouldn't discourage you from using them, as bending over backwards to do
everything with locks is prone to lead to code that is fast and *wrong*).

If all you need is exclusive access, use a lock, not a semaphore. A
semaphore is appropriate if you need to make sure at most X clients use a
resource at the same time (where X > 1). If X = 1 but you also need to
synchronize across processes, use the Mutex class.
 
Thanks for all of your answers, the difference is clear to me now. In my
case, a lock will be sufficient.

regards,

Carl
 
I believe your No should be a Yes. They are practically very different. As
you rightly pointed out, one is process wide only, the other is a kernel
object. Consequently, the underlying implementation is very differet - think
spin locks.
He asked whether they "execute exactly the same". There's a lot of
leeway in this phrase to answer the question either way. To me, the
important detail was the use of a named semaphore -- this is most
certainly *not* the same as using a lock, not even functionally,
because it requires that you only ever run one instance of your
program. That said, I'll gladly admit I answered "no" because I saw
the opportunity.

Funny thing is, I saw this quite recently as an actual bug. Making the
semaphore anonymous solved the problem. A classic case of not reading
the documentation, and the natural human urge to name things when you
have the opportunity, regardless of whether it's required.
 
Alvin Bruney said:
I believe your No should be a Yes. They are practically very different. As
you rightly pointed out, one is process wide only, the other is a kernel
object. Consequently, the underlying implementation is very differet -
think spin locks.

<history deleted>

Which one is a spin lock? Spin locks scare the bejesus out of me.

Thanks, Bob
 
Back
Top