C++创建信号量 CreateSemaphore

一、定义

 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