Let's say you have this:
Code:
long g_Xvariable = 0;
Void Func1() {
++g_Xvariable;
}
Void Func2() {
++g_Xvariable;
}
Now this code is pretty simple. If you execute this in a linear fashion it might end up as you want, like this in mnemonics:
Code:
mov eax,[g_Xvariable]
inc eax
mov [g_Xvariable],eax
;; Now thread 2 does it's stuff
mov eax,[g_Xvariable]
inc eax
mov [g_Xvariable],eax
This does what it's supposed to, great. But wait, Windows is a pre-emptive multitasking environment. This is what could actually happen:
Code:
mov eax,[g_Xvariable]
inc eax
mov eax,[g_Xvariable]
mov [g_Xvariable],eax
inc eax
mov [g_Xvariable],eax
This will come out to g_Xvariable being 1! In fact, you could have five thousand threads do this exact same algorithm but the output could still be 1.
To synchronize access to things like integers, you should use the windows family of Interlocked functions, thus we can optimize the above two sections of code to this:
Code:
long g_Xvariable = 0;
Void Func1() {
InterlockedIncrement(&g_Xvariable);
}
Void Func2() {
InterlockedIncrement(&g_Xvariable);
}
The interlocked functions are badass for integer synchronization. However, if you want to synchronize access to certain sections of code and not integers, you can use something called a critical section, and you can use one like this:
Code:
int g_Data[20];
CRITICAL_SECTION gcs_Data;
void Func1() {
EnterCriticalSection(&gcs_Data);
for(int i=0;i<20;i++)
g_Data[i] = i+1;
LeaveCriticalSection(&gcs_Data);
}
void Func2() {
EnterCriticalSection(&gcs_Data);
for(int i=0;i<20;i++)
printf("%d ",g_Data[i]);
LeaveCriticalSection(&gcs_Data);
}
That will print out 1-20 appropriately.
Note that with critical sections, before any thread tries to access the critical section resource it needs to be initialized with a call to InitializeCriticalSection, and when you're done with the section you need to deinitialize it with a call to DeleteCriticalSection