Click to See Complete Forum and Search --> : Is "i=i+1" thread-safe?
martho
April 23rd, 2003, 02:10 PM
Hello!
I got a question in multitasking: Imaging a preemptive multitasking system like you have in Win2000 or WinXP. You have 2 threads in the same app, which both accesses the same global variable i:
Thread 1: i = i + 1
Thread 2: i = i - 1
In assembler, this should be something like:
Step1: Load i from memory to register
Step2: Add 1 to register
Step3: Store i from register to memory
Imaging thread 2 is exeuted right after Step1 of Thread1: Then the result would be wrong.
Or is this compiled into one operation like:
Step1: Increment content of memory
So my questions are:
- Do I have to put semaphores around this?
- What happens if I use i = i + 2?
cvogt61457
April 23rd, 2003, 02:29 PM
A critical section around each usage of 'i' would protect the variable
from preemption errors.
All locations must use the same critical section.
Easier than a semaphore.
Caronte
April 23rd, 2003, 02:45 PM
If i is a global variable, you have to use a critical section, semaphore, or whatever you want to protect it...
It is a good practice to take care of all access to global variables.
Of course, if i is a local variable, you donīt have any problems, because they are different variables.
mdmd
April 23rd, 2003, 02:55 PM
Or you could look at the section "Interlocked Variable Access"
in the "Platform SDK: DLLs, Processes, and Threads" section of
the msdn;
For ex, these are two to look at.
InterlockedIncrement
InterlockExchangeAdd
TSYS
April 23rd, 2003, 03:01 PM
Your description of what would happen in assembler is correct, the second thread could interrupt the first thread at any time. Consider the following:
[Thread1]
Load AX with value of "i"
[Thread2]
Load AX with value of "i"
Subtract 1
Store AX as "i"
[Thread1]
Add 1
Store AX as "i"
The result would be that, according to Thread2, i - 1 = i + 1. And that's why you must use some sort of control to restrict access to data common to more than one thread.
But you are also correct in that the compiler would probably compile "i+1" to the assembler "inc i" (and "i-1" would be compiled as "dec i"), and there would be no pre-emptive interruption in the midst of the calculation. Wouldn't work for "i+2" though.
martho
April 24th, 2003, 08:36 AM
Thanx for all the answers!
If got one last question: Could someone explain what's the difference between a Semapohre (or Critical Section) and a Mutex?
A Semaphore (as I understood) garantuees that a part of a thread (which accesses global resources like the "i" in my first post) doesn't get interrupted. In my example, I would use:
Thread1:
Semaphore "MySemaphore"
i = i + 2
End Semapthore
Thread2:
Semaphore "MySemaphore"
i = i - 2
End Semapthore
What does a Mutex do then?
Caronte
April 24th, 2003, 08:47 AM
The mutex only allows one thread accessing the same variable (or resource) at the "same" time.
A semaphore can specify the maximun number of threads that are allowed to access a variable (or resource).
martho
April 24th, 2003, 08:50 AM
That means a mutex can be used like a semaphore: It "surrounds" the "critical section", in which the code accesses global resources. Right?
Caronte
April 24th, 2003, 08:53 AM
I would say that the semaphore can be used like a mutex.
In fact, the general use of a semaphore is acting as a mutex.
You are right as far as I know.
myron
October 18th, 2005, 12:07 AM
Semaphore can have it's max count as 1, and that's called Binary Semaphore, and others are Counting Sempahore.
Binary semaphore is just like Mutex.
Critical Section can be only used in single process, and that it's faster than Binary Semaphore and Mutex.
Marc G
October 18th, 2005, 03:00 AM
[ moved thread ]
Arjay
October 18th, 2005, 04:39 PM
A little late in replying, but check out the InterlockedXXX family of functions. InterlockedIncrement/InterlockedDecrement will allow you to safely change the variable without needing to supply your own synchronization.
Arjay
Marc G
October 19th, 2005, 02:47 AM
A little late in replying, ...
:lol: a little late... you do know that this thread was started in 04-23-2003, so it's more than 2 years late ;)
Arjay
October 19th, 2005, 03:24 PM
:lol: a little late... you do know that this thread was started in 04-23-2003, so it's more than 2 years late ;)
I don't normally check the thread times, but know it showed up in the multithreaded section yesterday.:thumb:
Just think of all the unnecessary critical section calls I could have saved had I answered two years ago.
Arjay
codeguru.com
Copyright 2007 Jupitermedia Corporation All Rights Reserved.