C++中Semaphore内核对象用法实例

C++中Semaphore内核对象用法实例

什么是Semaphore对象

Semaphore是一种同步内核对象,用于实现线程或进程之间的同步与互斥。它可以用来限制同时进行某项操作的线程或进程的数量。可以把Semaphore视为一个许可证表。在多任务操作系统中,如果操作系统中有多个线程或进程需要访问共享资源,那么当这些线程或进程数目超过一定限制时,就会发生资源竞争的情况,为了避免这种情况的发生,可以使用Semaphore对象进行同步控制和协调。

Semaphore对象具有两个标准操作:
- Wait():如果许可证表中没有许可证可用,则线程或进程被挂起并等待可用的许可证。否则,从许可证表中取出一个许可证,并继续执行。
- Signal():向许可证表中添加一个许可证,如果有被挂起的线程或进程在等待许可证,那么它们中的一个将被唤醒并收到许可证,否则,许可证将保留在许可证表中,等待下一次被取用。

Semaphore对象通常初始化为一个大于或等于零的整数,表示初始时许可证表中可用的许可证数量。如果Semaphore对象的计数器为0,则所有的Wait操作都会被阻塞,直到调用Signal操作为止。

Semaphore对象的使用方法

Semaphore对象通常包括以下步骤:
1. 创建Semaphore对象:使用CreateSemaphore函数创建一个Semaphore对象,指定其初始计数器、最大计数器、名称等参数。
2. Wait操作:使用WaitForSingleObject或WaitForMultipleObjects函数进行等待操作。
3. Signal操作:使用ReleaseSemaphore函数对Semaphore对象进行信号操作。
4. 关闭Semaphore对象:使用CloseHandle函数关闭Semaphore对象。

下面的示例展示了Semaphore对象的使用方法:

示例一

#include <Windows.h>
#include <iostream>

using namespace std;

int main() {
    HANDLE hSemaphore;
    DWORD dwWaitResult;

    // 创建Semaphore对象
    hSemaphore = CreateSemaphore(NULL, 1, 1, "MySemaphore");

    if (hSemaphore == NULL) {
        cout << "CreateSemaphore error: " << GetLastError() << endl;
        return 1;
    }

    // Wait操作
    dwWaitResult = WaitForSingleObject(hSemaphore, 5000);

    switch (dwWaitResult) {
        case WAIT_OBJECT_0:
            // 获取Semaphore对象成功
            cout << "获取Semaphore对象成功" << endl;
            break;
        case WAIT_TIMEOUT:
            // 超时
            cout << "等待获取Semaphore对象超时" << endl;
            break;
        default:
            // 错误
            cout << "WaitForSingleObject error: " << GetLastError() << endl;
            return 1;
    }

    // Signal操作
    if (!ReleaseSemaphore(hSemaphore, 1, NULL)) {
        cout << "ReleaseSemaphore error: " << GetLastError() << endl;
        return 1;
    }

    // 关闭Semaphore对象
    CloseHandle(hSemaphore);

    return 0;
}

代码中,使用CreateSemaphore函数创建了一个名为"MySemaphore"的Semaphore对象,其初始计数器和最大计数器都为1。使用WaitForSingleObject函数等待Semaphore对象,等待的时间为5秒,如果等待到了可用的许可证,则输出"获取Semaphore对象成功",调用ReleaseSemaphore函数对Semaphore对象进行Signal操作,并最后关闭Semaphore对象。

示例二

#include <Windows.h>
#include <iostream>
#include <vector>
#include <thread>

using namespace std;

HANDLE hSemaphore;
const int nThreadCount = 3;
vector<thread> vecThreads;

void ThreadProc(int nIndex) {
    DWORD dwWaitResult;

    dwWaitResult = WaitForSingleObject(hSemaphore, INFINITE);

    switch (dwWaitResult) {
        case WAIT_OBJECT_0:
            // 获取Semaphore对象成功
            cout << "线程[" << nIndex << "]获取Semaphore对象成功" << endl;
            Sleep(2000);
            break;
        default:
            // 错误
            cout << "WaitForSingleObject error: " << GetLastError() << endl;
    }

    ReleaseSemaphore(hSemaphore, 1, NULL);

    return;
}

int main() {
    int i;

    // 创建Semaphore对象
    hSemaphore = CreateSemaphore(NULL, 2, 2, "MySemaphore");

    if (hSemaphore == NULL) {
        cout << "CreateSemaphore error: " << GetLastError() << endl;
        return 1;
    }

    // 创建线程
    for (i = 0; i < nThreadCount; i++) {
        vecThreads.emplace_back(ThreadProc, i);
    }

    // 等待线程执行完成
    for (auto& thread: vecThreads) {
        thread.join();
    }

    // 关闭Semaphore对象
    CloseHandle(hSemaphore);

    return 0;
}

代码中,使用CreateSemaphore函数创建了一个名为"MySemaphore"的Semaphore对象,其初始计数器和最大计数器都为2。使用CreateThread函数创建了3个线程,线程函数为ThreadProc,该函数等待Semaphore对象,等待时间为无限,如果等待到了可用的许可证,则输出"线程[i]获取Semaphore对象成功",延迟2秒,并调用ReleaseSemaphore函数对Semaphore对象进行Signal操作。最后关闭Semaphore对象。

以上两个示例展示了常规的Semaphore对象使用方法,通过Semaphore对象可以实现线程同步控制和协调等功能,在实际的应用开发中,Semaphore对象的应用非常广泛。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++中Semaphore内核对象用法实例 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • c语言实现足球比赛积分统计系统

    使用C语言实现足球比赛积分统计系统 介绍 足球比赛积分统计系统是一个基本的数据管理系统,它能够记录球队之间的胜、负、平等信息,计算出每个球队的比赛积分。本文将详细讲解如何使用C语言实现一个简单的足球比赛积分统计系统。 准备工作 要使用C语言实现足球比赛积分统计系统,您需要了解一些基本的程序设计概念,例如: 变量 运算符 控制结构(如if/else) 循环结构…

    C 2023年5月22日
    00
  • C语言结构体大小分析

    title: C语言结构体大小分析 author: saopigqwq233 date: 2022-04-05 C语言结构体大小分析 一,基本类型 C语言自带的数据类型大小如下 数据类型 大小(字节) char 1 short 2 int 4 long 4或8 float 4 double 8 long double 16 二,自定义类型—struct …

    C语言 2023年4月17日
    00
  • Python中with上下文管理协议的作用及用法

    下面就来详细讲解“Python中with上下文管理协议的作用及用法”的完整攻略。 什么是上下文管理协议 在Python中,上下文管理指的是在资源使用中的安全获取和释放的机制。这个机制就是基于Python的上下文管理协议实现的。 上下文管理协议是指有赖于特定的方法支持协议的对象的协议。这些方法包括__enter__和__exit__,称为上下文管理器。使用这种…

    C 2023年5月23日
    00
  • C 可变参数

    C语言中的可变参数(variable arguments)是一种特殊的参数类型,可以允许函数接受不确定数量的参数。可变参数的使用需要引入 C 标准库的stdarg.h头文件,并且需要使用固定格式的函数。 可变参数函数的定义 可变参数函数的定义需要以下三个步骤: 定义函数传入的最后一个参数,以便在函数中定位可变参数的起始位置。 C int function_n…

    C 2023年5月10日
    00
  • Qt教程之QSqlQueryModel的使用详解

    Qt教程之QSqlQueryModel的使用详解 在Qt开发中,使用数据库是非常常见的需求。QSqlQueryModel是Qt提供的一个方便的数据模型类,可以与数据库进行交互,并提供了方便的方法进行数据的展示和编辑。本文将详细讲解如何使用QSqlQueryModel进行数据库的操作。 初始化QSqlQueryModel 在使用QSqlQueryModel进行…

    C 2023年5月23日
    00
  • Lua获取网络时间(获取时间同步服务器的时间)

    获取网络时间是一个常见的需求,可以借助在线时间同步服务器来获取当前的时间并更新本地时间,Lua也可以通过此方式来实现网络时间获取。 在Lua中获取网络时间最简单的方法是使用Luasocket库并连接在线时间同步服务器,这个库可以通过LuaRocks来安装。 以下是获取网络时间的基本步骤: 安装Luasocket库 可以通过LuaRocks来安装Luasock…

    C 2023年5月22日
    00
  • Matlab实现遗传算法的示例详解

    下面我会详细讲解一下“Matlab实现遗传算法的示例详解”的完整攻略,让您能够理解该示例的实现过程。 什么是遗传算法? 遗传算法是一种模拟自然进化过程的搜索算法,通过模拟进化过程实现对于最优解的搜索。遗传算法模拟的过程涉及到选择、交叉、变异等操作,从而在保持种群多样性的同时,逐步优化得到最优解。 遗传算法的基本流程 遗传算法的基本流程如下: 初始化种群,生成…

    C 2023年5月23日
    00
  • C#实现Json转DataTable并导出Excel的方法示例

    我将为你详细讲解“C#实现Json转DataTable并导出Excel的方法示例”的完整攻略。以下是该攻略的步骤及示例说明: 步骤一:将Json转为DataTable 使用C#实现Json转DataTable的方法有很多种,比如使用JSON.NET库等。我们以JSON.NET库为例,具体步骤如下: 引用Newtonsoft.Json库: 在Visual St…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部