C++ windows多线程同步--信号量
首先先介绍和windows信号量有关的两个API:创建信号量、释放信号量
HANDLE WINAPI CreateSemaphore( msdn官网解释
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
_In_ LONG lInitialCount,
_In_ LONG lMaximumCount,
_In_opt_ LPCTSTR lpName
);
第一个参数:安全属性,如果为NULL则是默认安全属性
第二个参数:信号量的初始值,要>=0且<=第三个参数
第三个参数:信号量的最大值
第四个参数:信号量的名称
返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄
BOOL WINAPI ReleaseSemaphore( msdn官网解释
_In_ HANDLE hSemaphore,
_In_ LONG lReleaseCount,
_Out_opt_ LPLONG lpPreviousCount
);
第一个参数:信号量句柄
第二个参数:释放后,信号量增加的数目
第三个参数:信号量增加前的值存放的地址,如果不需要则为NULL
返回值:释放是否成功
以上两个函数头文件:windows.h (另外还有个函数OpenSemaphore()可以打开其它进程创建的信号量) 本文地址
下面通过一个例子来说明信号量如何使用,这是一道IT公司笔试题:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
分析:这里我们要让三个线程按顺序依次打印ABC,即当一个线程在打印A时,另外两个线程不能够打印,而且打印完A以后,接下来必须打印B。我们使用三个信号量分别控制A B C的打印,打印完A就释放B的信号量,打印完B就释放C的信号量,打印完C就释放A的信号量。具体见下面代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 |
#include<string> #include<iostream> #include<process.h> #include<windows.h> using
namespace std; HANDLE
hsem1,hsem2,hsem3; //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall unsigned __stdcall threadFunA( void
*) { for ( int
i = 0; i < 10; i++){ WaitForSingleObject(hsem1, INFINITE); //等待信号量 cout<< "A" ; ReleaseSemaphore(hsem2, 1, NULL); //释放信号量 } return
1; } unsigned __stdcall threadFunB( void
*) { for ( int
i = 0; i < 10; i++){ WaitForSingleObject(hsem2, INFINITE); //等待信号量 cout<< "B" ; ReleaseSemaphore(hsem3, 1, NULL); //释放信号量 } return
2; } unsigned __stdcall threadFunC( void
*) { for ( int
i = 0; i < 10; i++){ WaitForSingleObject(hsem3, INFINITE); //等待信号量 cout<< "C" ; ReleaseSemaphore(hsem1, 1, NULL); //释放信号量 } return
3; } int
main() { //创建信号量 hsem1 = CreateSemaphore(NULL, 1, 1, NULL); hsem2 = CreateSemaphore(NULL, 0, 1, NULL); hsem3 = CreateSemaphore(NULL, 0, 1, NULL); HANDLE
hth1, hth2, hth3; //创建线程 hth1 = ( HANDLE )_beginthreadex(NULL, 0, threadFunA, NULL, 0, NULL); hth2 = ( HANDLE )_beginthreadex(NULL, 0, threadFunB, NULL, 0, NULL); hth3 = ( HANDLE )_beginthreadex(NULL, 0, threadFunC, NULL, 0, NULL); //等待子线程结束 WaitForSingleObject(hth1, INFINITE); WaitForSingleObject(hth2, INFINITE); WaitForSingleObject(hth3, INFINITE); //一定要记得关闭线程句柄 CloseHandle(hth1); CloseHandle(hth2); CloseHandle(hth3); CloseHandle(hsem1); CloseHandle(hsem2); CloseHandle(hsem3); } |
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3601252.html
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。