Race Conditions: Difference between revisions

From COMP15212 Wiki
pc>Yuron
No edit summary
 
gravatar W81054ch [userbureaucratinterface-adminsysopPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
m (1 revision imported)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{#set: Priority=3 | Summary=A race condition is normally a mistake, where two (or more) operations can complete in different orders - and thus leave different results - depending on issues such as the way threads are scheduled.}}<!--
{{#set: Priority=3 | Summary=A race condition is normally a mistake, where two (or more) operations can complete in different orders - and thus leave different results - depending on issues such as the way threads are scheduled.}}<!--
-->{{#invoke:Dependencies|add|Memory,4}}
-->{{#invoke:Dependencies|add|Memory,4}}
Race conditions are not an issue in single-threaded systems; nor are
Race conditions are not an issue in single-threaded systems; nor are they an issue where only a single thread/process can write to a variable or claim a resource.  However if there are multiple interacting threads (or processes, or process<strong>or</strong>s) then this class of problem may emerge.
they an issue where only a single thread/process can write to a
variable or claim a resource.  However if there are multiple
interacting threads (or processes, or process<strong>or</strong>s) then this class
of problem may emerge.


Race conditions <em>can</em> occur when write access is available to
Race conditions <em>can</em> occur when write access is available to variables, records, resources, files … from different
variables, records, resources, files … from different
threads/processes because they are running <em>asynchronously</em> which means the overall behaviour of the system is <strong>non-deterministic</strong>. The result of the code can be altered by the way the threads are scheduled … which is <em>not controlled by the programmer</em>.
threads/processes because they are running <em>asynchronously</em> which
means the overall behaviour of the system is <strong>non-deterministic</strong>.
The result of the code can be altered by the way the threads are
scheduled … which is <em>not controlled by the programmer</em>.


There’s a short (7 mins.) [https://www.youtube.com/watch?v=C11oPTm4K84 video] introduction here.
There’s a short (7 mins.) [https://www.youtube.com/watch?v=C11oPTm4K84 video] introduction here.
Line 33: Line 25:
print(x)
print(x)
</syntaxhighlight>
</syntaxhighlight>
What is printed?  Either the <code>x := x + 1;</code> came first – in which case
What is printed?  Either the <code>x := x + 1;</code> came first – in which case the answer is <code>2</code> <em>because the result is then overwritten</em>, or the <code>x := 2;</code> won the race in which case the answer is <code>3</code>.  The point is that the answer is <em>not determined by the programmer</em> and so is likely to be an error and Bad Things might happen.
the answer is <code>2</code> <em>because the result is then overwritten</em>, or the <code>x := 2;</code> won the race in which case the answer is <code>3</code>.  The point is
that the answer is <em>not determined by the programmer</em> and so is likely
to be an error and Bad Things might happen.


<em>If spotted in advance</em> it is typically possible to identify and guard
<em>If spotted in advance</em> it is typically possible to identify and guard [[Atomicity|critical sections]] of code with some form of [[mutual exclusion]] element.  These force these sections to be <em>deterministic</em>.
[[Atomicity|critical sections]] of code with some form of [[mutual exclusion]] element.  These force these sections to be <em>deterministic</em>.


[https://en.wikipedia.org/wiki/Race_condition <strong>Race hazards</strong>]
[https://en.wikipedia.org/wiki/Race_condition <strong>Race hazards</strong>] typically <em>appear</em> rarely and unpredictably, making them difficult to find and debug (so it’s best not to allow them in in the first place!).  Whilst not confined to O.S. code, the multi-threaded nature of many system applications is ‘fertile ground’ for race conditions and an O.S. will often provide primitives for mutexes and [[semaphores]] to help with protecting against them.
typically <em>appear</em> rarely and unpredictably, making them difficult to
find and debug (so it’s best not to allow them in in the first
place!).  Whilst not confined to O.S. code, the multi-threaded nature
of many system applications is ‘fertile ground’ for race
conditions and an O.S. will often provide primitives for mutexes and
[[semaphores]] to help with protecting against them.
<blockquote>
<blockquote>
[https://searchstorage.techtarget.com/definition/race-condition Here]
[https://searchstorage.techtarget.com/definition/race-condition Here] is another definition (and example) you might find useful.
is another definition (and example) you might find useful.
</blockquote>
</blockquote>
----
----
=== TOCTOU ===
=== TOCTOU ===
[https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use Time Of Check to Time Of Use] is a term used in the classification of certain bugs caused by race
[https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use Time Of Check to Time Of Use] is a term used in the classification of certain bugs caused by race hazards.  Fundamentally, the issue is that a test is made to see if something is permitted <em>and then</em> it is done.  There is the potential for conditions to be changed between the check and the use <em>unless</em> the test and commit is <em>atomic</em>.
hazards.  Fundamentally, the issue is that a test is made to see if
something is permitted <em>and then</em> it is done.  There is the potential
for conditions to be changed between the check and the use <em>unless</em>
the test and commit is <em>atomic</em>.


Here’s a illustrative [https://en.wikipedia.org/wiki/Northeast_blackout_of_2003 anecdote].
Here’s a illustrative [https://en.wikipedia.org/wiki/Northeast_blackout_of_2003 anecdote].
----
----
 
{{BookChapter|6|257-287}}
{{PageGraph}}
{{PageGraph}}
{{Category|Deadlock}}
{{Category|Deadlock}}
{{Category|Processes}}
{{Category|Processes}}

Latest revision as of 10:03, 5 August 2019

Depends on Memory

Race conditions are not an issue in single-threaded systems; nor are they an issue where only a single thread/process can write to a variable or claim a resource. However if there are multiple interacting threads (or processes, or processors) then this class of problem may emerge.

Race conditions can occur when write access is available to variables, records, resources, files … from different threads/processes because they are running asynchronously which means the overall behaviour of the system is non-deterministic. The result of the code can be altered by the way the threads are scheduled … which is not controlled by the programmer.

There’s a short (7 mins.) video introduction here.

Here is some pseudocode:

x := 1;  // Shared variable

parallel
{ // Thread 1
  <stuff>
  x := x + 1;
  <more stuff>
},
{ // Thread 2
  <different stuff>
  x := 2;
  <yet more stuff>
} 
print(x)

What is printed? Either the x := x + 1; came first – in which case the answer is 2 because the result is then overwritten, or the x := 2; won the race in which case the answer is 3. The point is that the answer is not determined by the programmer and so is likely to be an error and Bad Things might happen.

If spotted in advance it is typically possible to identify and guard critical sections of code with some form of mutual exclusion element. These force these sections to be deterministic.

Race hazards typically appear rarely and unpredictably, making them difficult to find and debug (so it’s best not to allow them in in the first place!). Whilst not confined to O.S. code, the multi-threaded nature of many system applications is ‘fertile ground’ for race conditions and an O.S. will often provide primitives for mutexes and semaphores to help with protecting against them.

Here is another definition (and example) you might find useful.


TOCTOU

Time Of Check to Time Of Use is a term used in the classification of certain bugs caused by race hazards. Fundamentally, the issue is that a test is made to see if something is permitted and then it is done. There is the potential for conditions to be changed between the check and the use unless the test and commit is atomic.

Here’s a illustrative anecdote.


Also refer to: Operating System Concepts, 10th Edition: Chapter 6, pages 257-287


Articles on Deadlock
Atomicity • Deadlock • File Locking • Locks • Multi Threading • Multiprocessors • Mutual exclusion • Operation Ordering • Race Conditions • Reentrancy • Semaphores • Starvation • Threads
Articles on Processes
About this resource • Atomicity • Containers • Context • Context Switching • Daemons • Fork Unix • Hypervisor • Idle • Interprocess Communication • Multi Threading • Mutual exclusion • Pipes • Pointer Arithmetic • Process Control Block (PCB) • Process Priority • Process Scheduling • Process States • Processes • Queues • Queues Extra • Race Conditions • Real Time • Resources • Scheduler • Signal and Wait • Sleep • Starvation • Synchronisation • Thrashing • Threads • Unix Signals