信号量在多线程中,主要是用于线程的同步或者限制线程运行的数量。
所谓同步,当流程 1 运行在线程 1 中,流程 2 运行在线程 2 中,流程 2 必须在流程 1 结束之后才能开始执行。你会怎么做,所有就需要给出一个流程 1 结束的信号。
在信号来之前,让线程 2 先在某个位置等待,这个使用方式和互斥锁有点类似,互斥从某种意义上也是一种同步,只是互斥锁更倾向于保护共同资源。信号量大于 0 的时候就代表有信号,不需要等待,但不仅仅是 1。
下面的这个例子设置了 3 个线程,设置最大同时只运行 2 个进程。
#include<Windows.h> #include<iostream> using namespace std; //创建一个信号量 HANDLE hSemaphore; //有参数 DWORD WINAPI MyThread2(LPVOID lpParamter) { while (1) { WaitForSingleObject(hSemaphore,INFINITE); cout << "MyThread1 Runing :"<<"线程2" << endl; Sleep(2000); ReleaseSemaphore(hSemaphore,1,NULL);//释放信号量 } } //无参数 DWORD WINAPI MyThread1(LPVOID lpParamter) { while (1) { //信号量减1,如果等于0就进入睡眠,待大于0之后再减 WaitForSingleObject(hSemaphore,INFINITE); cout << "MyThread2 Runing"<<"线程1" << endl; Sleep(2000); //信号量加1 ReleaseSemaphore(hSemaphore,1,NULL);//释放信号量 } } //无参数 DWORD WINAPI MyThread3(LPVOID lpParamter) { while (1) { //信号量减1,如果等于0就进入睡眠,待大于0之后再减 WaitForSingleObject(hSemaphore,INFINITE); cout << "MyThread2 Runing"<<"线程3" << endl; Sleep(2000); //释放信号量,信号量加1 ReleaseSemaphore(hSemaphore,2,NULL); } } int main() { //创建一个信号量,2是初值,3是最大值 hSemaphore =CreateSemaphore(NULL,2,3,NULL); //第三个参数是线程函数的地址,第四个参数是传到线程的参数指针 HANDLE hThread = CreateThread(NULL, 0, MyThread1, NULL, 0, NULL); //释放句柄 CloseHandle(hThread); HANDLE hThread1 = CreateThread(NULL, 0, MyThread2, NULL, 0, NULL); CloseHandle(hThread); HANDLE hThread3 = CreateThread(NULL, 0, MyThread3, NULL, 0, NULL); //释放句柄 CloseHandle(hThread3); while(1); return 0; }
结果可以看到,三个线程交替运行 2 个