接下来我们介绍利用关键代码段实现线程同步的方法。
关键代码段(临界区)工作在用户方式下。它是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。
关键代码段机制,创建---进入---离开---删除.
1 InitializeCriticalSection( 2 LPCRITICAL_SECTION lpCriticalSection 3 );
创建初始化函数参数是一个out类型,即作为返回值使用。因此在之前我们需要构造一个CRITICAL_SECTION结构型对象,然后将该对象地址传递给InitializeCriticalSection函数,由系统自动维护该对象。
进入关键代码段函数:EnterCriticalSection
离开关键代码段函数:LeaveCriticalSetion
删除函数: DeleteCriticalSection
这三个函数都只有一个参数,该参数为CRITICAL_SECTION结构型对象指针。
接下来将之前的例程用关键代码段来实现多线同步处理:
1 #include<windows.h>
2 #include<iostream.h>
3
4 DWORD WINAPI Fun1Proc(LPVOID lpParameter);
5 DWORD WINAPI Fun2Proc(LPVOID lpParameter);
6
7 int tick=100;
8 //HANDLE hMutex;
9 //HANDLE g_hEvent;
10 CRITICAL_SECTION g_cs;
11 void main()
12 {
13 HANDLE hThread1;
14 HANDLE hThread2;
15 /*g_hEvent=CreateEvent(NULL,FALSE,FALSE,"MyThread");
16 if(g_hEvent)
17 {
18 if(ERROR_ALREADY_EXISTS==GetLastError())
19 {
20 cout<<"Only one intance can run."<<endl;
21 return;
22 }
23 }
24 SetEvent(g_hEvent);*/
25 InitializeCriticalSection(&g_cs);
26 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
27 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
28 CloseHandle(hThread1);
29 CloseHandle(hThread2);
30 //Create mutex object.
31 //hMutex=CreateMutex(NULL,TRUE,"dadad");
32 /*if(hMutex)
33 {
34 if(ERROR_ALREADY_EXISTS==GetLastError())
35 {
36 cout<<"Only one intance can run."<<endl;
37 return;
38 }
39 }
40 WaitForSingleObject(hMutex,INFINITE);
41 ReleaseMutex(hMutex);
42 ReleaseMutex(hMutex);*/
43
44 Sleep(4000);
45 //CloseHandle(g_hEvent);
46 DeleteCriticalSection(&g_cs);
47 }
48 //thread function
49 DWORD WINAPI Fun1Proc(LPVOID lpParameter)
50 {
51 while(true)
52 {
53 //request object using
54 //WaitForSingleObject(hMutex,INFINITE);
55 //WaitForSingleObject(g_hEvent,INFINITE);
56 //ResetEvent(g_hEvent);
57 Sleep(1);
58 EnterCriticalSection(&g_cs);
59 Sleep(1);
60 if(tick>0)
61 {
62 //Sleep(1);
63 cout<<"Thread1 sell tick:"<<tick--<<endl;
64 //SetEvent(g_hEvent);
65 LeaveCriticalSection(&g_cs);
66 }
67 else
68 {
69 //SetEvent(g_hEvent);
70 LeaveCriticalSection(&g_cs);
71 break;
72 }
73 //ReleaseMutex(hMutex);
74 }
75 return 0;
76 }
77 //thread function
78 DWORD WINAPI Fun2Proc(LPVOID lpParameter)
79 {
80
81 while(true)
82 {
83 //request object using
84 //WaitForSingleObject(hMutex,INFINITE);
85 //WaitForSingleObject(g_hEvent,INFINITE);
86 //ResetEvent(g_hEvent);
87 Sleep(1);
88 EnterCriticalSection(&g_cs);
89 Sleep(1);
90 if(tick>0)
91 {
92 //Sleep(1);
93 cout<<"Thread2 sell tick:"<<tick--<<endl;
94 //SetEvent(g_hEvent);
95 LeaveCriticalSection(&g_cs);
96 }
97 else
98 {
99 //SetEvent(g_hEvent);
100 LeaveCriticalSection(&g_cs);
101 break;
102 }
103 //ReleaseMutex(hMutex);
104 }
105 return 0;
106 }
我们在进入临界区之前用了个延时,预留给两线程之间交替时间间隔。
编译运行,结果和之前的一样。

当然了,临界代码区有速度快,但容易出现锁死的情况,例如:
1 //thread function
2 DWORD WINAPI Fun1Proc(LPVOID lpParameter)
3 {
4 while(true)
5 {
6 //request object using
7 //WaitForSingleObject(hMutex,INFINITE);
8 //WaitForSingleObject(g_hEvent,INFINITE);
9 //ResetEvent(g_hEvent);
10 Sleep(1);
11 EnterCriticalSection(&g_cs0);
12 Sleep(1);
13 EnterCriticalSection(&g_cs);
14 ......
15 }
16 //thread function
17 DWORD WINAPI Fun2Proc(LPVOID lpParameter)
18 {
19
20 while(true)
21 {
22 //request object using
23 //WaitForSingleObject(hMutex,INFINITE);
24 //WaitForSingleObject(g_hEvent,INFINITE);
25 //ResetEvent(g_hEvent);
26 Sleep(1);
27 EnterCriticalSection(&g_cs);
28 Sleep(1);
29 EnterCriticalSection(&g_cs0);
30 if(tick>0)
31 .....
32 }
这情况就出现了锁死的情况。是编写代码的时候必须要注意避免的。这也是其与互斥对象,事件对象有较大区别的地方。
End.
谢谢.