Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# lock statement, what object to lock on?

I have 3 questions that I need help with.

  1. What are the correct objects/references to be passed as lock statement parameter? I've seen a lot of sample codes and I noticed that the objects/references passed in could possibly be non related to the current class or any other class in the program as long as the access modifier static is non public? E.g.:

    private Object anyObj = new Object(); lock(anyObj){.....}  private static readonly object Locker = new object(); lock(Locker){.....} 

    It just doesn't make sense to me.

  2. I found a sample code in MSDN about multi threading that uses lock statements too. In the sample there are two try/catch blocks with the Monitor.Wait() within it. If I understand the logic correctly, the readerFlag will forbid the program to ever enter the try/catch block at all.
    The code is example 2 from here:
    http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx

  3. How do I run a thread that runs in the background as long as the Windows Form is active?

like image 710
user1885498 Avatar asked Dec 07 '12 13:12

user1885498


People also ask

Why do we write C?

We write C for Carbon Because in some element the symbol of the element is taken form its first words and Co for Cobalt beacause in some elements the symbol of the element is taken from its first second letters, so that the we don't get confuse.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...


1 Answers

How and what you lock on depends upon what you're doing.

Let's say that you're working with a device of some kind - say a coffee maker. You might have a class that looks like this:

public CoffeeMaker {     private IntPtr _coffeeHandle;     private Object _lock = new Object(); } 

In this case, you are protecting access to the _coffeeHandle - a pointer/handle to a real physical device, so this is pretty easy:

public int AvailableCups {     get {         lock (_lock) {             return GetAvailableCups(_coffeeHandle); // P/Invoked         }     } }  public void Dispense(int nCups) {     lock (_lock) {         int nAvail = GetAvailableCups(_coffeeHandle);         if (nAvail < nCups) throw new CoffeeException("not enough coffee.");         Dispense(_coffeeHandle, nCups); // P/Invoked     }  } 

So if I'm running a multithreaded app, I (probably) don't want to read the number of cups that are available while I'm dispensing (maybe it's a hardware error). By protecting accesses to the handle, I can ensure that. Also, I can't be asked to dispense while I'm already dispensing - that would be bad, so that's protected too. Finally, I don't dispense unless I have enough coffee available and you notice that I don't use my public property to check that - this way the action of ensuring there's enough coffee and dispensing are tied together. The magic word is atomic - they can't be cut apart without creating issues.

You use a static object as a lock if you have one and only one instance of a resource that needs protecting. Think, "do I have a singleton?" and that will be a guideline for when you might need a static lock. For example, let's say that CoffeeMaker has a private constructor. Instead, you have a factory method that constructs coffee machines:

static Object _factLock = new Object();  private CoffeeMaker(IntPtr handle) { _coffeeHandle = handle; }  public static CoffeeMaker GetCoffeeMaker() {     lock (_factLock) {         IntPtr _handle = GetCoffeeMakerHandle(); // P/Invoked         if (_handle == IntPtr.Zero) return null;         return new CoffeeMaker(_handle);     }  } 

Now in this case, it feels like CoffeeMaker should implement IDisposable so that handle gets taken care of, because if you don't release it then somebody might not be getting their coffee.

There are a few problems though - maybe if there's not enough coffee, we should make more - and that takes a long time. Heck - dispensing coffee takes a long time, which is why we're careful to protect our resources. Now you're thinking that really all this coffee maker stuff should be in a thread of its own and that there should be an event that gets fired when the coffee is done, and then it starts to get complicated and you understand the importance of knowing what you're locking on and when so that you don't block making coffee because you asked how many cups are there.

And if the words "deadlock", "atomic", "monitor", "wait", and "pulse" all sound foreign to you, you should consider reading up on multiprocessing/multithreading in general and see if you can solve the fair barbershop problem or the dining philosophers problem, both quintessential examples of resource contention.

like image 61
plinth Avatar answered Oct 10 '22 03:10

plinth