What is a race condition?

后端 未结 18 2560
谎友^
谎友^ 2020-11-21 04:52

When writing multithreaded applications, one of the most common problems experienced is race conditions.

My questions to the community are:

What is the rac

相关标签:
18条回答
  • 2020-11-21 05:13

    A sort-of-canonical definition is "when two threads access the same location in memory at the same time, and at least one of the accesses is a write." In the situation the "reader" thread may get the old value or the new value, depending on which thread "wins the race." This is not always a bug—in fact, some really hairy low-level algorithms do this on purpose—but it should generally be avoided. @Steve Gury give's a good example of when it might be a problem.

    0 讨论(0)
  • 2020-11-21 05:15

    A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, you don't know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are "racing" to access/change the data.

    Problems often occur when one thread does a "check-then-act" (e.g. "check" if the value is X, then "act" to do something that depends on the value being X) and another thread does something to the value in between the "check" and the "act". E.g:

    if (x == 5) // The "Check"
    {
       y = x * 2; // The "Act"
    
       // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
       // y will not be equal to 10.
    }
    

    The point being, y could be 10, or it could be anything, depending on whether another thread changed x in between the check and act. You have no real way of knowing.

    In order to prevent race conditions from occurring, you would typically put a lock around the shared data to ensure only one thread can access the data at a time. This would mean something like this:

    // Obtain lock for x
    if (x == 5)
    {
       y = x * 2; // Now, nothing can change x until the lock is released. 
                  // Therefore y = 10
    }
    // release lock for x
    
    0 讨论(0)
  • 2020-11-21 05:15

    A race condition is a kind of bug, that happens only with certain temporal conditions.

    Example: Imagine you have two threads, A and B.

    In Thread A:

    if( object.a != 0 )
        object.avg = total / object.a
    

    In Thread B:

    object.a = 0
    

    If thread A is preempted just after having check that object.a is not null, B will do a = 0, and when thread A will gain the processor, it will do a "divide by zero".

    This bug only happen when thread A is preempted just after the if statement, it's very rare, but it can happen.

    0 讨论(0)
  • 2020-11-21 05:16

    Consider an operation which has to display the count as soon as the count gets incremented. ie., as soon as CounterThread increments the value DisplayThread needs to display the recently updated value.

    int i = 0;
    

    Output

    CounterThread -> i = 1  
    DisplayThread -> i = 1  
    CounterThread -> i = 2  
    CounterThread -> i = 3  
    CounterThread -> i = 4  
    DisplayThread -> i = 4
    

    Here CounterThread gets the lock frequently and updates the value before DisplayThread displays it. Here exists a Race condition. Race Condition can be solved by using Synchronzation

    0 讨论(0)
  • 2020-11-21 05:19

    Race conditions occur in multi-threaded applications or multi-process systems. A race condition, at its most basic, is anything that makes the assumption that two things not in the same thread or process will happen in a particular order, without taking steps to ensure that they do. This happens commonly when two threads are passing messages by setting and checking member variables of a class both can access. There's almost always a race condition when one thread calls sleep to give another thread time to finish a task (unless that sleep is in a loop, with some checking mechanism).

    Tools for preventing race conditions are dependent on the language and OS, but some comon ones are mutexes, critical sections, and signals. Mutexes are good when you want to make sure you're the only one doing something. Signals are good when you want to make sure someone else has finished doing something. Minimizing shared resources can also help prevent unexpected behaviors

    Detecting race conditions can be difficult, but there are a couple signs. Code which relies heavily on sleeps is prone to race conditions, so first check for calls to sleep in the affected code. Adding particularly long sleeps can also be used for debugging to try and force a particular order of events. This can be useful for reproducing the behavior, seeing if you can make it disappear by changing the timing of things, and for testing solutions put in place. The sleeps should be removed after debugging.

    The signature sign that one has a race condition though, is if there's an issue that only occurs intermittently on some machines. Common bugs would be crashes and deadlocks. With logging, you should be able to find the affected area and work back from there.

    0 讨论(0)
  • 2020-11-21 05:20

    Race condition is not only related with software but also related with hardware too. Actually the term was initially coined by the hardware industry.

    According to wikipedia:

    The term originates with the idea of two signals racing each other to influence the output first.

    Race condition in a logic circuit:

    Software industry took this term without modification, which makes it a little bit difficult to understand.

    You need to do some replacement to map it to the software world:

    • "two signals" => "two threads"/"two processes"
    • "influence the output" => "influence some shared state"

    So race condition in software industry means "two threads"/"two processes" racing each other to "influence some shared state", and the final result of the shared state will depend on some subtle timing difference, which could be caused by some specific thread/process launching order, thread/process scheduling, etc.

    0 讨论(0)
提交回复
热议问题