How did it dead lock?

  • Thread starter Thread starter euan_woo
  • Start date Start date
E

euan_woo

Hi,
Sometimes my program stops and when I break it I see 2 threads both
waiting at a lock statement trying to lock the same object. If I look
up the call stack of these threads there aren't any other calls to lock
statements so I don't see how it's possible for anything to be locked.

Can anyone explain this to me?

Thanks
 
Hi,

Is it possible that another thread other than the 2 you just mentioned
is holding the lock?

Brian
 
If you are trying to lock(this) then it can lead in to dead locks. Did
you try using SOS/Windbg to identify the dead lock and the stack trace?
Also post a smaple code.
 
Hello,

thanks for the help.

I am trying to lock(this) and that's where one of the threads stops.
The other thread stops while trying to lock the same object although
this time it isn't 'this'.
If I can't lock(this) then what should I do?

If it hangs again how do I use Windbg to help me?

Thanks again!
 
Helge Jensen said:
Complicating your code to defend against outside misuse is a loosing battle.

The solution to bad-outside-code is to let the bad-outside-coders accept
responsibility for their actions and develop their skill (if possible).
Not to spend unlimit development-time, readability and code-complexity,
up front.

If you buy that argument, would you suggest that everything should be
public, too?

Locking on explicit lock objects doesn't take unlimited development
time, nor does it impact readability or code complexity. Indeed, it
adds flexibility, and can allows more useful locking strategies, which
can detect deadlocks and offer timeouts, too:
http://www.pobox.com/~skeet/csharp/miscutil/usage/locking.shtml
 
Jon said:
If you buy that argument, would you suggest that everything should be
public, too?

Yes, I pretty much do. A side-benefit is much less complicated white-box
testing, since the "hiding" of implementation of state is only a hint,
not enforced.

Where possible, also outside computing, I prefer accountability to
prevention.

I admit that I occasionally declare members protected, when I know they
will change implmentation/signature within a short timeframe, or if they
are helper-functions local to the class -- since C# have no free
functions and these helpers aren't part of the behaiour of the class.

For code without security implications I believe in documenting the
risks and letting the user decide.

Prefixing with "_" can be enough documentation that this method or that
member is not for casual use, if that practice is well enough known in
the context.

I have yet to see a real example where private methods or properties do
any real good.
Locking on explicit lock objects doesn't take unlimited development

No, but it does require the programmer to do something more complicated.
Rules accumulate.

I don't particularly object to the use of an explicit lock-object. What
I don't like is stuff like:

"We strongly discourage the use of lock(this). Since other, completely
unrelated code can choose to lock on that object as well"

Which blanket states that a practice should be followed. I don't see any
other reason stated anywhere in the article.

If someone lock(x) on an object, what are they expecting?

lock(this) is preferrable in many cases, most notably those where a
data-structure internally need to lock, but callers also occasionally
need to mutually exclusively invoke multiple methods without intervention.
time, nor does it impact readability or code complexity. Indeed, it
adds flexibility, and can allows more useful locking strategies, which

I am well aware that lock(this) isn't the solution to all locking. But
it's not a bad practice that needs to be banned or workarounded either.
can detect deadlocks and offer timeouts, too:

And if those properties are needed, then by all means implement them.

I have come to prefer simplicity over almost anything, even correctness
upto a point. If it's complicated, it's probably wrong or bug-filled --
if it's simple then it may just be correct.

A very gifted co-worker and the C2 wiki: http://c2.com/cgi/wiki have
turned me from my old habits of closing everything I didn't see a use
for to a practice where I honestly present everything along with hints
about which risks are taken by using a specific level of knowledge about
the implementation.

This link seems to be broken? i get 404.
 
It is again up to each individual in taking up the semantics of
programming. I guess your point might be applicable for the code that
you write one day and throw away the next day. If you are writing
serious code (like library provider) you want to ensure that the code
performs the way it is supposed to and don't let the bad outside
coders jeopardize you're library.
 
Helge Jensen said:
Yes, I pretty much do. A side-benefit is much less complicated white-box
testing, since the "hiding" of implementation of state is only a hint,
not enforced.

In that case, I think we so fundamentally disagree that I haven't got
time to fully address your concerns at the moment.

Just a couple of things then:
No, but it does require the programmer to do something more complicated.
Rules accumulate.

If someone doesn't like rules, they certainly shouldn't attempt
threading. It's inherently complicated, and there are rules that you
really *must* follow in order to make things work reliably.

If someone lock(x) on an object, what are they expecting?

lock(this) is preferrable in many cases, most notably those where a
data-structure internally need to lock, but callers also occasionally
need to mutually exclusively invoke multiple methods without intervention.

If you don't know what's locking on each reference, you can't hope to
be confident that you won't get deadlock IMO.

A very gifted co-worker and the C2 wiki: http://c2.com/cgi/wiki have
turned me from my old habits of closing everything I didn't see a use
for to a practice where I honestly present everything along with hints
about which risks are taken by using a specific level of knowledge about
the implementation.

When you expose everything, you allow people to rely on everything - in
other words, the current implementation. That's why I don't like the
overuse of inheritance - it fixes the implementation more than a nice
black-box encapsulation. I hate the idea that I'm not free to change my
code later on.
This link seems to be broken? i get 404.

Whoops - not sure why the s crept in. Try this:
http://www.pobox.com/~skeet/csharp/miscutil/usage/locking.html
 
Jon said:
In that case, I think we so fundamentally disagree that I haven't got
time to fully address your concerns at the moment.

I understand. I also accept that my views are not "the one true view".
Disageement isn't bad in my book.
Just a couple of things then:

When I say "rules accumulate", perhaps I should have said "these
practices accumulate". It's important to observe the ones that add value
to your program.

Other examples are "use stringbuffer to build strings", "declare an
interface", "declare local-variables of the most abstract possible
type", "don't Thread.Abort()".

These are all good advice, but not nessesarily always apply.
If someone doesn't like rules, they certainly shouldn't attempt
threading. It's inherently complicated, and there are rules that you
really *must* follow in order to make things work reliably.

I have written many multithreaded programs. Trying to do multiple things
without threads is much more complicated than with threads.

It's not "rules" as such I oppose, it's the rules that add no value or
add more complexity than value.

If a race-condition exists but have little impact (for example, it
theoretically doesn't redraw the GUI nicely) I don't nessesarily remove
it -- it depends on the complication vs. the value.
If you don't know what's locking on each reference, you can't hope to
be confident that you won't get deadlock IMO.

Surely true. But is "guaranteed no deadlock, no matter what the caller
does", a valuable property, which I should complicate the code for? Is
it even a desireable property?

lock(this) specifies a protocol. Sometimes that protocol is the right
thing -- and often it's not that bad if it isn't. You probably shouldn't
lock on objects that you haven't coordinated a locking strategy with
(that's good advice :)

Often, I would rather have the code deadlock, so the misconception shows up.

Is it really my responsibility to defend all classes from code that does
lock on something it hasn't cleared locking semantics with?
When you expose everything, you allow people to rely on everything - in
other words, the current implementation. That's why I don't like the
overuse of inheritance - it fixes the implementation more than a nice
black-box encapsulation. I hate the idea that I'm not free to change my
code later on.

That's why I state in the code how "private" this or that is, but
instead of enforcing that privacy, I hint it -- relying on the "other
guy"s judgement on whether it's acceptable or not in his code/project to
rely on it.

I also prefer composition to inheritance where possible, if it's not too
much work.

It's a question of whos freedom is important, mine to change or his to
look. If you don't enforce but hint, we can both have our freedom, under
accuntability.

I look forward to reading it, I usually enjoy your insightfull comments.
 
Naveen said:
It is again up to each individual in taking up the semantics of
programming. I guess your point might be applicable for the code that
you write one day and throw away the next day. If you are writing
serious code (like library provider) you want to ensure that the code
performs the way it is supposed to and don't let the bad outside
coders jeopardize you're library.

I would agree that "it all depends". What we don't seem to agree on is
the degree of depends :)

It should be common knowledge that synchronization using lock is an
aspect, and thus require communication between all lockers.

If "outside coders" does lock on an object from the library, should you
"save them from a deadlock"? or should you give them the oppotunity to
control the thread-safety of sequences of method invocations by the same
mechanism that your library uses?

It's all just down to which protocol you supply.
 
Helge said:
I have yet to see a real example where private methods or properties do
any real good.

Well, take most of the .NET Framework BCL as a case in point. I'd hate
to wade through a bunch of properties and methods that were never
intended to be called. One of the most important factors in designing
a good framework is to think about the public interface from the
caller's perspective. Make things easy to use correctly and difficult
to abuse. They'll love you for it. By littering the public interface
you not only make it more difficult to modify, version, etc., you've
also made it more difficult for developers to use correctly.

Brian
 
Brian said:
to abuse. They'll love you for it. By littering the public interface
you not only make it more difficult to modify, version, etc., you've
also made it more difficult for developers to use correctly.

The public/internal/protected/private modifier does not document
anything, it allows/prevents access. The documentation generator
shouldn't drive accessability of data.

Some languages get by very nicely without a concept access restriction,
for example python. In python it is well known that things starting with
"_" is implementation dependent.

If I choose to rely on implementation details, it will be my loss when
the provider changes implementation.
 
Helge Jensen said:
The public/internal/protected/private modifier does not document
anything, it allows/prevents access. The documentation generator
shouldn't drive accessability of data.

However, if I type:

myString.

then only the public members are presented by intellisense - without
applying extra attributes, *all* your members are going to be presented
to the developer, instead of only those which you actually want the dev
to call in the normal run of things.
Some languages get by very nicely without a concept access restriction,
for example python. In python it is well known that things starting with
"_" is implementation dependent.

Perhaps the IDEs for Python have been tailored to that way of working
then - that's certainly not true of C# (etc) IDEs. It sounds like
you're trying to use the language in a way it wasn't really designed to
be used, which is rarely a good idea IME.
 
Helge Jensen said:
I understand. I also accept that my views are not "the one true view".
Disageement isn't bad in my book.
Sure.


When I say "rules accumulate", perhaps I should have said "these
practices accumulate". It's important to observe the ones that add value
to your program.

Other examples are "use stringbuffer to build strings", "declare an
interface", "declare local-variables of the most abstract possible
type", "don't Thread.Abort()".

These are all good advice, but not nessesarily always apply.

No - but I would consider it better to know the rule and understand the
places where it doesn't apply than to not know it at all.
I have written many multithreaded programs. Trying to do multiple things
without threads is much more complicated than with threads.

Absolutely. That doesn't make threaded coding simple though :)
It's not "rules" as such I oppose, it's the rules that add no value or
add more complexity than value.

If a race-condition exists but have little impact (for example, it
theoretically doesn't redraw the GUI nicely) I don't nessesarily remove
it -- it depends on the complication vs. the value.

True - but you *do* need to understand the situation, IMO, otherwise
you could have a nastier problem waiting to happen.
Surely true. But is "guaranteed no deadlock, no matter what the caller
does", a valuable property, which I should complicate the code for? Is
it even a desireable property?

It certainly is for all of the work I've ever done, which is mostly
server work where the service really mustn't deadlock. Even client apps
give a *very* bad impression if they deadlock.
lock(this) specifies a protocol. Sometimes that protocol is the right
thing -- and often it's not that bad if it isn't. You probably shouldn't
lock on objects that you haven't coordinated a locking strategy with
(that's good advice :)

Often, I would rather have the code deadlock, so the misconception shows up.

Is it really my responsibility to defend all classes from code that does
lock on something it hasn't cleared locking semantics with?

It does depend on what you're writing, but I think it's better to make
the locking as independent as possible from other objects and document
places where some degree of interaction is/may be inevitable.
That's why I state in the code how "private" this or that is, but
instead of enforcing that privacy, I hint it -- relying on the "other
guy"s judgement on whether it's acceptable or not in his code/project to
rely on it.

I prefer to give APIs which are as bullet-proof as possible.
I also prefer composition to inheritance where possible, if it's not too
much work.

Good to see we agree on something :)
It's a question of whos freedom is important, mine to change or his to
look. If you don't enforce but hint, we can both have our freedom, under
accuntability.

If you're basically saying "this may not work in a future version" then
pretty much any responsible programmer will avoid that API completely -
in which case you've just *added* complexity by reducing the
signal/noise ratio.
 
Back
Top