multithreadingrace-conditionmultitasking

How does a queue solve the thread race problem?


I saw that there are many ways in order to avoid race conditions when tackling with multithreading, but the most common are mutexes and queues. I cannot understand how a queue could make an application thread safe as long as the threads may populate the queue in a chaotic order.


Solution

  • I cannot understand how a queue could make an application thread safe as long as the threads may populate the queue in a chaotic order.

    First of all, let's get "thread safe" out of the way. "Thread safety" really only should be used to describe the components (functions, modules, classes, libraries, etc.) that can be used to build an application.

    A component is thread-safe if it guarantees to behave in some useful and well documented way when it is concurrently used by more than one thread. Since you're talking about queues, here's what you might expect from a thread-safe queue:

    1. Every item that is put() into the queue eventually can be take()en from the queue.
    2. No item can ever be take()en that was not put().
    3. *IF* the program puts two items into the queue in a certain order, then they will be take()en in the same order,

    BUT,

    1. If the program allows concurrent put() calls to the queue, then the queue cannot guarantee the order in which those items actually will appear in the queue.

    "Thread safety" doesn't really apply to applications because the user of an application cannot choose whether to use it in a multi-threaded way or in a single-threaded way. That choice is baked-in by the application author. An application either is correct (it works as expected) or else it isn't.

    So, let's re-state your question:

    I cannot understand how a queue could make an application correct as long as the threads may populate the queue in a chaotic order.

    It can't. If the application depends on objects being put() into a queue in some particular order, then it is the application programmer's responsibility to ensure that the put() calls do not overlap. If the calls are allowed to overlap, there is no way that the queue could possibly know which order the application programmer intended for the items to go in to the queue.