|
|
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;
struct threadGlobal {
int x;
int y;
};
CRITICAL_SECTION cs_out;
CRITICAL_SECTION cs_g;
CRITICAL_SECTION cs_l;
CRITICAL_SECTION cs_tl;
CRITICAL_SECTION cs_tgv;
DWORD tlsIndex;
int global = 0;
void l() {
static int localStatic = 0;
EnterCriticalSection(&cs_l);
localStatic ++;
LeaveCriticalSection(&cs_l);
EnterCriticalSection(&cs_tgv);
threadGlobal* tgv =
(threadGlobal*) TlsGetValue(tlsIndex);
tgv->x ++;
tgv->y ++;
LeaveCriticalSection(&cs_tgv);
EnterCriticalSection(&cs_out);
cout << " l: " << localStatic << ", tgx: " << tgv->x << endl << flush;
LeaveCriticalSection(&cs_out);
}
void g() {
EnterCriticalSection(&cs_g);
global++;
LeaveCriticalSection(&cs_g);
EnterCriticalSection(&cs_tgv);
threadGlobal* tgv =
(threadGlobal*) TlsGetValue(tlsIndex);
tgv->x ++;
tgv->y ++;
LeaveCriticalSection(&cs_tgv);
EnterCriticalSection(&cs_out);
cout << " g: " << global << ", tgx: " << tgv->x << endl << flush;
LeaveCriticalSection(&cs_out);
}
void tg() {
EnterCriticalSection(&cs_tgv);
threadGlobal* tgv =
(threadGlobal*) TlsGetValue(tlsIndex);
tgv->x=0;
tgv->y=0;
LeaveCriticalSection(&cs_tgv);
}
void tl() {
__declspec (thread) static int threadLocalStatic = 0;
EnterCriticalSection(&cs_tl);
threadLocalStatic++;
LeaveCriticalSection(&cs_tl);
EnterCriticalSection(&cs_tgv);
threadGlobal* tgv =
(threadGlobal*) TlsGetValue(tlsIndex);
tgv->x ++;
tgv->y ++;
LeaveCriticalSection(&cs_tgv);
EnterCriticalSection(&cs_out);
cout << "tl: " << threadLocalStatic << ", tgx: " << tgv->x << endl << flush;
LeaveCriticalSection(&cs_out);
}
unsigned int __stdcall TF(void*) {
TlsSetValue(
tlsIndex,
GlobalAlloc(GPTR,sizeof(threadGlobal))
);
tg();
l();
g();
tl();
return 0;
}
int main(int argc, char* argv[]) {
HANDLE hT[2];
InitializeCriticalSection(&cs_l);
InitializeCriticalSection(&cs_g);
InitializeCriticalSection(&cs_tl);
InitializeCriticalSection(&cs_tgv);
InitializeCriticalSection(&cs_out);
tlsIndex = TlsAlloc();
hT[0] = (HANDLE) _beginthreadex(0,0,TF,0,0,0);
hT[1] = (HANDLE) _beginthreadex(0,0,TF,0,0,0);
WaitForMultipleObjects(2,hT,TRUE,INFINITE);
DeleteCriticalSection(&cs_l );
DeleteCriticalSection(&cs_tl);
DeleteCriticalSection(&cs_g );
DeleteCriticalSection(&cs_tgv);
DeleteCriticalSection(&cs_out);
GlobalFree(TlsGetValue(tlsIndex));
TlsFree(tlsIndex);
return 0;
}
The output is:
l: 1, tgx: 1
g: 1, tgx: 2
l: 2, tgx: 1
g: 2, tgx: 2
tl: 1, tgx: 3
tl: 1, tgx: 3
|