Search code examples
multithreading

Do regular infinite loops count as livelocks?


As I understand it:

  • Livelock: a thread won't make progress but yet it's executing forever (the thread is infinitely alive): for example, it's in an loop infinitely trying to get access to a shared resource that will never be available again.
  • Deadlock: a thread doesn't make progress but it's not even executing (the thread is infinitely sleeping, and hence dead): it's waiting to be waken up by the OS based on a condition that will never happen.
  • Starvation: a thread doesn't make progress and it's blocking (like in a deadlock), but the condition being waited for to be waken up do occur, it just happens that there are other threads that always take my place before me.

First, are those definitions more or less correct? If they are, do they also apply for single thread programs? For example:

// begin of useful work
until (some_buggy_condition_that_will_never_be_satisfied())
    do_something();
// end of useful work

In the example above, the loop will execute forever because the condition, that has nothing to do with shared resources, has a bug in it and will never be satisfied. So the thread:

  • It's executing.
  • To do useful work the loop must end
  • The loop will never end because the condition to end will never be satisfied

So that list omatches my livelock definition above, it just that I'm using the term outside concurrency contexts. Is that ok?


Solution

  • It takes more than one thread to have a live lock. We say "live lock" when a system of interacting threads continually repeats some kind of back-up-and-retry behavior instead of doing any work. Picture a doorway, and picture two or more obsequious gentlemen who all want to go through at the same time. But all they ever do is take turns saying, "No! After you, I insist." And, nobody ever goes through the door.

    An infinite loop is not a live lock. There are lots of programs in which threads loop forever doing useful work. We only ever say "live lock" when no work is being done.

    It takes more than one thread to have a deadlock. We say "deadlock" when there's a group of threads in which none of them can do anything at all until it acquires a resource that one of the other members of the group is holding. Picture a one-lane bridge, with lines of vehicles wanting to cross in both directions, but aggressive drivers at the head each line are shouting at each other, "I won't move even one inch until you move out of my way."

    Starvation is kind of like half of a live lock. It has the same continual cycle of back-off-and-try-again, except that the cycle allows at least one thread to make progress while obstructing at least one other thread. Picture one timid person who is afraid to push their way through a door against a seeming endless line of people coming through in the other direction.


    Update You asked,

    do [those definitions] also apply for single thread programs?

    IMO, there is no reason to use any of those terms when talking about a single-threaded program. You're only going to confuse people if you do that.

    For example:

    // begin of useful work
    until (some_buggy_condition_that_will_never_be_satisfied())
        do_something();
    // end of useful work
    

    ...matches my "livelock" definition above, it just that I'm using the term outside concurrency contexts. Is that ok?

    Speaking for myself, I would just call that a loop with a buggy exit condition.


    Note! Some authors will use the phrase "self deadlock" when a thread stalls trying to get a second lock on a resource for which it already holds one lock. But, if you're talking about a single-threaded program, then why would there even be a lock for the thread to hang itself on?