1 /*know it before
2 //unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
3 //第1个参数:安全属性,NULL为默认安全属性
4 //第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0
5 //第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址)
6 //第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针
7 //第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂)
8 //第6个参数:用于记录线程ID的地址
9 //如果你的编程只调用 Win32 API/SDK ,就放心用 CreateThread;如果要用到
10 //C++ 运行时间库,那么就要使用 _beginthreadex ,并且需要在编译环境中选择 Use MultiThread Lib/DLL
11 //绝对不要调用系统自带的CreateThread函数创建新的线程,而应该使用_beginthreadex,除非你在线程中绝不使用需要tiddata结构的运行时库函数
12
13 //WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
14 //threadNum 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64)
15 //hThread 句柄数组的指针 HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore )数组
16 //BOOL bWaitAll 等待的类型,如果为TRUE 则等待所有信号量有效在往下执行,FALSE 当有其中一个信号量有效时就向下执行
17 //DWORD dwMilliseconds 超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。
18
19 //CloseHandle(hThread[i]);
20 //只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,放弃控制权。并没有结束线程。
21 */
22
23 //用Interlocked系列函数实现线程同步实例如下:
24 //旋转锁 当然这种方法会浪费cpu时间,因为cpu要不断地执行InterlockedExchange()函数,单CPU不推荐这种方法。
25 #include <iostream>
26 using namespace std;
27 #include <process.h>
28 #include <windows.h>
29 const int threadNum=10;
30 HANDLE hThread[threadNum];
31 volatile unsigned int ISOK=0;
32 unsigned int _stdcall Interlocked(PVOID threadId)
33 {
34 while(InterlockedExchange(&ISOK,1)==1) ;
35 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
36 Sleep(100);
37 cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
38 InterlockedExchange(&ISOK,0);
39 return 0;
40 }
41
42 void InterlockedTest()
43 {
44 int threadId[threadNum];
45 for(int i=0;i<threadNum;i++)
46 {
47 threadId[i]=i+1;
48 }
49 cout<<"1:用Interlocked系列函数实现线程同步"<<endl;
50 for(int i=0;i<threadNum;i++){
51 hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Interlocked,threadId+i, 0, NULL);
52 }
53 WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
54 for(int i=0;i<threadNum;i++)
55 {
56 CloseHandle(hThread[i]);
57 }
58 }
59
60 //用CRITICAL_SECTION及其系列函数实现线程同步实例如下:
61 //关键段
62 // #include <iostream>
63 // using namespace std;
64 // #include <process.h>
65 // #include <windows.h>
66 // const int threadNum=10;
67 // HANDLE hThread[threadNum];
68 CRITICAL_SECTION g_cs;//构造一个CRITICAL_SECTION实例
69 unsigned int _stdcall CriticalSection(PVOID threadId)
70 {
71 EnterCriticalSection(&g_cs);//进入关键段
72 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
73 Sleep(100);
74 cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
75 LeaveCriticalSection(&g_cs);//进入关键段
76 return 0;
77 }
78
79
80 void CriticalSectionTest()
81 {
82 int threadId[threadNum];
83 for(int i=0;i<threadNum;i++)
84 {
85 threadId[i]=i+1;
86 }
87 InitializeCriticalSection(&g_cs);//初始化g_cs的成员
88 cout<<"2:用CRITICAL_SECTION及其系列函数实现线程同步"<<endl;
89 for(int i=0;i<10;i++){
90 hThread[i]=(HANDLE)_beginthreadex(NULL, 0, CriticalSection,threadId+i, 0, NULL);
91 }
92 WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
93 for(int i=0;i<threadNum;i++)
94 {
95 CloseHandle(hThread[i]);
96 }
97 DeleteCriticalSection(&g_cs);//删除关键段
98 }
99
100 /*
101 SRWLock的目的和关键段是一样的,就是对资源的保护,不让其他线程访问。
102 不同的是,它区分线程是读线程还是写线程。
103 我们都是知道,一个资源可以同时被多个线程同时读,就是不能同时读,或是读写。
104 也是是说写必须是独占的方式,而读可以以共享的方式访问,如果以共享的方式访问肯定就比CRITICAL_SECTION性能好。
105 */
106 //用RTL_SRWLOCK及其系列函数实现线程同步实例如下:
107 //读写锁
108 RTL_SRWLOCK lock;//构造一个RTL_SRWLOCK实例
109 unsigned int _stdcall SrwLock(PVOID threadId)
110 {
111 AcquireSRWLockExclusive(&lock);//进入读写锁
112 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
113 Sleep(100);
114 cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
115 ReleaseSRWLockExclusive(&lock);//进入读写锁
116 return 0;
117 }
118
119 void SrwLockTest()
120 {
121 int threadId[threadNum];
122 for(int i=0;i<threadNum;i++)
123 {
124 threadId[i]=i+1;
125 }
126 InitializeSRWLock(&lock);//初始化lock的成员
127 cout<<"3:用RTL_SRWLOCK及其系列函数实现线程同步"<<endl;
128 for(int i=0;i<10;i++){
129 hThread[i]=(HANDLE)_beginthreadex(NULL, 0, SrwLock,threadId+i, 0, NULL);
130 }
131 WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
132 for(int i=0;i<threadNum;i++)
133 {
134 CloseHandle(hThread[i]);
135 }
136
137 }
138 //用事件内核对象实现线程同步实例如下:
139 //事件
140 HANDLE event1;
141
142 unsigned int _stdcall Event(PVOID threadId)
143 {
144 WaitForSingleObject(event1,INFINITE);
145 int* p=(int*)threadId;
146 cout<<"线程:"<<*p<<"开始"<<endl;
147 Sleep(100);
148 cout<<"线程:"<<*p<<"结束"<<endl;
149 SetEvent(event1);
150 return 1;
151 }
152
153 void EventTest()
154 {
155 int threadId[threadNum];
156 for(int i=0;i<threadNum;i++)
157 {
158 threadId[i]=i+1;
159 }
160 event1=CreateEvent(NULL,false,true,NULL);
161 cout<<"4:用事件内核对象实现线程同步"<<endl;
162 for(int i=0;i<threadNum;i++)
163 {
164 hThread[i] =(HANDLE)_beginthreadex(NULL, 0, Event ,threadId+i, 0, NULL);
165 }
166 WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
167 for(int i=0;i<threadNum;i++)
168 {
169 CloseHandle(hThread[i]);
170 }
171 CloseHandle(event1);
172 }
173
174 //用信号量内核对象实现线程同步实例如下:
175 //信号量
176 HANDLE semaphore;
177 unsigned int _stdcall Semaphore(PVOID threadId)
178 {
179 WaitForSingleObject(semaphore, INFINITE);
180 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl;
181 Sleep(100);
182 cout<<"线程:"<<*(int*)threadId<<"结束"<<endl;
183 ReleaseSemaphore(semaphore,1,NULL);
184 return 0;
185 }
186
187 void SemaphoreTest()
188 {
189 int threadId[threadNum];
190 for(int i=0;i<threadNum;i++)
191 {
192 threadId[i]=i+1;
193 }
194 semaphore=CreateSemaphore(NULL,1,1,NULL);
195 cout<<"5:用信号量内核对象实现线程同步"<<endl;
196 for(int i=0;i<10;i++){
197 hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Semaphore,threadId+i, 0, NULL);
198 }
199 WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);
200 for(int i=0;i<threadNum;i++)
201 {
202 CloseHandle(hThread[i]);
203 }
204 CloseHandle(semaphore);
205 }
206 void main()
207 {
208 InterlockedTest();
209 CriticalSectionTest();
210 SrwLockTest();
211 EventTest();
212 SemaphoreTest();
213 }