一、定义
Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。
1.创建或打开命名或未命名的信号量对象。
1 2 3 4 5 6 | HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD LONG lInitialCount, // initial count LONG lMaximumCount, // maximum count LPCTSTR lpName // object name ) |
参数说明:
1 2 3 4 5 | lpSemaphoreAttributes:为信号量的属性,一般可以设置为NULL lInitialCount:信号量初始值,必须大于等于0,而且小于等于 lpMaximumCount,如果lInitialCount 的初始值为0,则该信号量默认为unsignal状态,如果lInitialCount的初始值大于0,则该信号量默认为signal状态, lMaximumCount: 此值为设置信号量的最大值,必须大于0 lpName:信号量的名字,长度不能超出MAX_PATH ,可设置为NULL,表示无名的信号量。当lpName不为空时,可创建有名的信号量,若当前信号量名与已存在的信号量的名字相同时,则该函数表示打开该信号量,这时参数lInitialCount 和 lMaximumCount 将被忽略。 |
2.释放信号量函数
1 2 3 4 5 6 7 | OOL ReleaseSemaphore( HANDLE hSemaphore, // handle to semaphore LONG lReleaseCount, // count increment amount LPLONG lpPreviousCount // previous count); 参数说明: hSemaphore:信号量句柄, lReleaseCount:释放的数量,一般完成一个等待后调用此函数释放一个信号量,使得信号量平衡。 lpPreviousCount :存放以前信号量的数量 ,一般可为NULL. |
二、实例
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | // 信号量.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <Windows.h> #include <tchar.h> const TCHAR* szSemaphoreA = _T("_SemaphoreA_"); const TCHAR* szSemaphoreB = _T("_SemaphoreB_"); const TCHAR* szSemaphoreC = _T("_SemaphoreC_"); DWORD WINAPI Thread_1(LPVOID param); DWORD WINAPI Thread_2(LPVOID param); DWORD WINAPI Thread_3(LPVOID param); HANDLE hSM_1; HANDLE hSM_2; HANDLE hSM_3; HANDLE hThread_1; HANDLE hThread_2; HANDLE hThread_3; int main() { // 创建三个信号量 hSM_1 = CreateSemaphore(NULL, 1, 1, szSemaphoreA);//开始为signal状态 hSM_2 = CreateSemaphore(NULL, 0, 1, szSemaphoreB);//开始为unsignal状态,等待hSM_1释放 hSM_3 = CreateSemaphore(NULL, 0, 1, szSemaphoreC);//开始为unsignal状态,等待hSM_2 //创建三个线程 hThread_1 = CreateThread(NULL, 0, Thread_1, NULL, 0, NULL); hThread_2 = CreateThread(NULL, 0, Thread_2, NULL, 0, NULL); hThread_3 = CreateThread(NULL, 0, Thread_3, NULL, 0, NULL); //等待三个线程都执行完 WaitForSingleObject(hThread_1, INFINITE); WaitForSingleObject(hThread_2, INFINITE); WaitForSingleObject(hThread_3, INFINITE); //三个线程都执行完 printf("\n\n\t main end \n"); //关闭句柄 CloseHandle(hThread_1); CloseHandle(hThread_2); CloseHandle(hThread_3); CloseHandle(hSM_1); CloseHandle(hSM_2); CloseHandle(hSM_3); return 0; } DWORD WINAPI Thread_1(LPVOID param) { for (int i = 0; i < 10; i++) { DWORD dwWait = WaitForSingleObject(hSM_1, INFINITE); //每一个wait过后信号量的数量自动减1,这样就达到了控制同步 printf("A"); ReleaseSemaphore(hSM_2, 1, NULL); } return 0; } DWORD WINAPI Thread_2(LPVOID param) { for (int i = 0; i < 10; i++) { WaitForSingleObject(hSM_2, INFINITE); printf("B"); ReleaseSemaphore(hSM_3, 1, NULL); } return 0; } DWORD WINAPI Thread_3(LPVOID param) { for (int i = 0; i < 10; i++) { WaitForSingleObject(hSM_3, INFINITE); printf("C "); ReleaseSemaphore(hSM_1, 1, NULL); } system("pause"); return 0; } |

参考:
https://www.cnblogs.com/priarieNew/p/9753419.html
https://blog.csdn.net/KLKFL/article/details/80575074?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
https://blog.csdn.net/qq_30483585/article/details/79564712?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase