Re: Threads - why isn't a whole object locked when ...?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Sat, 24 Jan 2009 16:30:31 -0800, <beginwithl@xxxxxxxxx> wrote:

[...]
2) Book suggests that if you are locking down a region of code within
apublic member, it is safer to declare a private object member
variable to serve as a token:

class Printer
{
private object threadLock = new object();
public void PrintNumbers()
{
lock ( threadLock )
{ …}
}
}


Now why would having a public token in a public method represent a
security risk:

It's not a security risk. It's a deadlock risk.

All of your questions are answerable by pointing out that you have an incorrect mental model of what it means to "lock" something. Thread synchronization (which is what the "lock" statement does) does _not_ lock an object at all. It's entirely cooperative between threads, and it's simply a way for multiple threads to coordinate access to shared data, or to synchronize execution of a specific block of code (or both).

One might say that the name of the "lock" statement is misleading. That is, while it's entirely sensible to people who are familiar with standard thread synchronization techniques, in reality it's not actually locking anything. Instead, it's using the reference as a sort of traffic signal for other threads, which are cooperating, to respect.

The "lock" statement passes the given object reference to the Monitor.Enter() method, which has a specific defined behavior in that until you later call Monitor.Leave() or Monitor.Wait() using the same object, no other call to Monitor.Enter() can return. That's all. It has no way of literally locking the entire object. Windows just doesn't provide for that kind of synchronization model (nor do other mainstream platforms, for that matter).

As for the question about using an internal reference instead of the "this" reference, the point of that is that the "this" reference is visible to other code you don't have control over. And if you use "this" to synchronize, there's a risk that some other code might use the same reference to synchronize, resulting in a different, unpredicted code path where the same reference is being used to synchronize. This may lead, at a minimum, to your own code path getting blocked unexpectedly, and in the worst case, could lead to a deadlock scenario where that reference is used in synchronization, along with some other reference as well, but taken in different orders (a classic way to get into deadlock).

Pete
.



Relevant Pages

  • Re: Classes and thread safety
    ... or the data is data found in an instance member. ... If the data is shared across multiple instances of a class, then the synchronization itself is going to need to be shared across multiple instances. ... On the other hand, for data that is accessed only by one instance of a class at a time, using a statically allocated and stored object reference for synchronization would be wasteful. ... Coarse or lower granularity means that the locking is done broadly, with large swaths of code being protected by the synchronization, preventing other code from accessing the data for long periods of time, or preventing a large amount of code from accessing the data at once. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: switch using strings
    ... to avoid the use of language features when those language features offer ... required System.Object type when a reference type is required. ... references for synchronization, _that_ is clearly not something the ... One wonders why there wasn't a specific Lock type whose sole purpose was to be used in synchronized and which had the wait and notify methods? ...
    (comp.lang.java.programmer)
  • Re: Is this thread safe?
    ... > I was using Environment.NewLine as a ref type to lock which did work. ... > switch to Environment.OSVersion which is a demand allocated reference ... you'll get cross-application domain synchronization when putting a lock on ... For instance if you make o a string reference; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: locking and cache coherence
    ... The PT writes its data buffer, grabs and releases a lock and then writes a byte to the pipe, the CT wakes up and now processes the buffer. ... From the previous discussion, memory synchronization of the PT's buffer write would be guaranteed at release of its lock, so the CT sees live data. ... To counter this with an utterly stupid, arbitrary oversimplification: suppose the locking done by the PT does spill the cache of the processor running the PT to main memory, but the locking *not* done by the CT may not have a chance to refresh the cache of the processor running the CT. ...
    (comp.programming.threads)
  • Re: Confusion: Threading & COM Interop
    ... reference to call a method, the COM interop layer will marshal the call to ... the correct apartment/thread, note that here the COM call is synchronous so ... > locking in the methods of COMForms, which are been called with Invoke ... No additional synchronization needed, the apartment is STA so only one ...
    (microsoft.public.dotnet.languages.csharp)