Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

locking a resource via lock within try. Is it wrong?

Tags:

Is there anything wrong with using lock with a try block? I remember reading somewhere that we should always try to put minimum amount of code within try block and lock itself internally uses a try-finally block, do you guys see something wrong here.I need to deal with the fact that the code within that lock block can throw exception

try   {      lock(syncblk)      {           // do some processing       }    }   catch(Exception e)   {       // do something with exception   }   
like image 927
Silverlight Student Avatar asked May 13 '11 20:05

Silverlight Student


People also ask

When to use locks in programming?

Locks are used to guard a shared data variable, like the account balance shown here. If all accesses to a data variable are guarded (surrounded by a synchronized block) by the same lock object, then those accesses will be guaranteed to be atomic — uninterrupted by other threads.

What does it mean to lock a thread?

The LOCK THREAD statement ensures that no other thread executes. This condition remains in effect until the thread is unlocked (with UNLOCK THREAD) or the thread terminates.

Why do we use lock 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 lock synchronization?

In computer science, a lock or mutex (from mutual exclusion) is a synchronization primitive: a mechanism that enforces limits on access to a resource when there are many threads of execution.


1 Answers

I need to deal with the fact that the code within that lock block can throw exception

And there's your problem. That's a terrible situation to be in.

Why are you locking in the first place? Usually the reason why you lock something is because you want to implement the following logic:

  • lock the door
  • make a mess
  • clean it up
  • unlock the door

If you do that, then no one who honours the locked door ever sees the mess.

For example, you might want to swap values of variables "left" and "right" in a threadsafe manner, so you:

  • take the lock
  • read the left variable into tempLeft
  • read the right variable into tempRight
  • write tempLeft into right
  • we just made a mess; the original value of 'right' has gone missing
  • write tempRight into left
  • we've cleaned up the mess, all is well with the world again
  • release the lock

Now suppose an exception is thrown after the mess is made. What happens? We jump straight to the unlock, leaving the mess for another thread to see.

That's why you should never throw an exception inside a lock; it completely defeats the purpose of the lock! The whole point of a lock is to ensure that state is always observed to be consistent by all threads except the one responsible for cleaning up the mess.

If you have an exception that can be thrown from inside a lock, the best thing to do is to get out of that horrible situation. If you can't do that, then make sure that you can either (1) destroy the process utterly as soon as the exception escapes the lock, so that the mess you made cannot cause data loss or other harm -- do a FailFast and nuke the process from orbit, it's the only way to be sure -- or (2) write rollback code that undoes whatever operation you were attempting before the lock is exited; that is, clean up the mess back to the original state.

If the latter is your strategy then don't put the try block outside the lock; it's useless there because the instant control leaves the lock via the exception another thread can be crashing and dying because of the mess you left exposed to it. Put the try that deals with the exception inside the lock:

lock(whatever) {     try     {         MakeAMess();     }     finally     {         CleanItUp();         // Either by completing the operation or rolling it back          // to the pre-mess state     } } 

If you have strong reliability requirements then dealing with locked critical sections which can throw exceptions is an extremely difficult programming task best left to experts; you might consider using a constrained execution region if you find yourself in this situation a lot.

like image 80
Eric Lippert Avatar answered Nov 16 '22 22:11

Eric Lippert