【WINAPI】CreateSemaphore_信号量

2023-05-16

【WINAPI】CreateSemaphore_信号量

  • 1. 注册信号量函数
    • 1.1 参数
    • 1.2 返回值
  • 2. 释放信号量函数
    • 2.1. 参数
    • 2.2. 返回值
  • 3. WaitForSingleObject
    • 3.2. 参数
    • 3.3. 返回值
  • 4. 例子
    • 4.1 运行结果图

1. 注册信号量函数

CreateSemaphore函数创建一个已命名或未命名的信号量对象

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, 
  LONG lInitialCount, 
  LONG lMaximumCount, 
  LPCTSTR lpName 
);

1.1 参数

  • lpSemaphoreAttributes:[IN] 设置为NULL;
  • lInitialCount:[IN] 指定信号量对象的初始计数,此值必须大于或等于零且小于或等于lMaximumCount
    • 当信号量的计数大于零时,会发出信号状态;
    • 在信号量为零时,则不会发出信号状态。
    • 每当等待函数释放等待信号量的线程时,计数就会减少一。通过调用ReleaseSemaphore函数将计数增加指定的数量。
  • lMaximumCount:[IN]指定信号量对象的最大计数。该值必须大于零。
  • lpName:[IN]指向以空值结尾的字符串的长指针,该字符串指定信号量对象的名称。名称限制为MAX_PATH字符,并且可以包含除反斜杠路径分隔符(\)之外的任何字符。名称比较区分大小写。
    • 如果lpName与现有命名信号对象的名称匹配,则lInitialCount和lMaximumCount参数将被忽略,因为它们已在创建过程中设置。
    • 如果lpName为NULL,则创建没有名称的信号量对象。
    • 如果lpName信号量名称不与事件,互斥对象或文件映射对象共享名称空间。

1.2 返回值

如果函数成功,则返回值是信号量对象的句柄。

2. 释放信号量函数

ReleaseSemaphore`函数将指定的信号量对象的技术增加指定的数量。

BOOL ReleaseSemaphore(
  HANDLE hSemaphore, 
  LONG lReleaseCount, 
  LPLONG lpPreviousCount 
);

2.1. 参数

  • hSemaphore:[IN]处理信号量对象,输入CreateSemaphore函数返回的句柄
  • lReleaseCount:[IN]指定信号量对象的当前计数要增加的数量。该值必须大于零。
    • 如果指定的数量将导致信号量的计数超过创建信号量时指定的最大计数,则计数不会更改,函数将返回FALSE。
  • lpPreviousCount:指向32位变量的长指针,用于接收信号量的先前计数。如果不需要上一个计数,则此参数可以为NULL。

2.2. 返回值

如果函数成功,则返回值为非零。如果函数失败,则返回值为零。

3. WaitForSingleObject

WaitForSingleObject等待,直到指定的对象处于发信号状态或超时间隔过去

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD  dwMilliseconds
);

3.2. 参数

  • hHandle:[In]对象的句柄
  • dwMilliseconds:[In]超时间隔(以毫秒为单位)
    • 如果指定了非零值,则函数将等待,直到发出信号通知对象或间隔过去为止。
    • 如果dwMilliseconds为零,则如果未用信号通知对象,则函数不会进入等待状态;否则,函数将进入等待状态
    • 如果dwMillisecondsINFINITE,则该函数仅在信号通知对象时返回。

3.3. 返回值

如果函数成功,则返回值指示导致函数返回的事件。它可以是以下值之一。

返回值返回码/值描述
WAIT_ABANDONED0x00000080L指定的对象是互斥对象,在拥有线程终止之前,拥有互斥对象的线程未释放该互斥对象。互斥对象的所有权授予调用线程,并且互斥状态设置为无信号。如果互斥锁正在保护持久状态信息,则应检查其一致性。
WAIT_OBJECT_00x00000000L指示指定对象的状态。
WAIT_TIMEOUT0x00000102L超时时间间隔过去了,并且对象的状态没有信号。
WAIT_FAILED(DWORD)0xFFFFFFFF该功能失败。要获取扩展的错误信息,请调用GetLastError

4. 例子

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

using namespace std;
/*
HANDLE CreateSemaphore(
	LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
	LONG lInitialCount,
	LONG lMaximumCount,
	LPCTSTR lpName
);
*/
HANDLE Hthread_1;
HANDLE Hthread_2;
HANDLE Hthread_3;

HANDLE Hsem1;
HANDLE Hsem2;
HANDLE Hsem3;

DWORD WINAPI thread_1(LPVOID param)
{
	for (int i = 0; i < 10; i++)
	{
		DWORD dwWait = WaitForSingleObject(Hsem1, INFINITE);
		cout << "A";
		ReleaseSemaphore(Hsem2, 1, NULL);
	}
	return 0;
}
DWORD WINAPI thread_2(LPVOID param)
{
	for (int i = 0; i < 10; i++)
	{
		DWORD dwWait = WaitForSingleObject(Hsem2, INFINITE);
		cout << "B";
		ReleaseSemaphore(Hsem3, 1, NULL);
	}
	return 0;
}
DWORD WINAPI thread_3(LPVOID param)
{
	for (int i = 0; i < 10; i++)
	{
		DWORD dwWait = WaitForSingleObject(Hsem3, INFINITE);
		cout << "C";
		ReleaseSemaphore(Hsem1, 1, NULL);
	}
	return 0;
}

int main()
{

	Hsem1 = CreateSemaphore(NULL, 1, 1, NULL);
	Hsem2 = CreateSemaphore(NULL, 0, 1, NULL);
	Hsem3 = CreateSemaphore(NULL, 0, 1, NULL);

	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);

	cout << endl << "-------------over-------------" << endl;

	CloseHandle(Hthread_1);
	CloseHandle(Hthread_2);
	CloseHandle(Hthread_3);
	CloseHandle(Hsem1);
	CloseHandle(Hsem2);
	CloseHandle(Hsem3);
	system("pause");
	return 0;
}

4.1 运行结果图

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【WINAPI】CreateSemaphore_信号量 的相关文章

随机推荐

  • golang获取postgres或clickhouse连接

    span class token keyword package span edgedb span class token keyword import span span class token punctuation span span
  • grpc-gateway插件:让客户端通过调http接口来远程调用grpc服务

    背景 xff1a 公司内部各服务 java pyhton go 想调取中台数据中心数据 xff0c 中台有两种服务搭建选择 xff1a 1 REST http请求 2 RPC 远程过程调用 实现及遇到的坑 使用Go将HTTP JSON转编码
  • ubuntu安装和卸载python3.8

    背景 xff1a 工作中 xff0c 可能会分配虚拟机给到开发者 xff0c 开发者需要在上面调试 xff0c 开发 xff0c 打包等操作 xff0c 依赖python环境 操作 网上安装步骤很多 xff0c 但很多文章描述的不够清晰 x
  • golang单例模式加载服务配置

    golang中单例模式体现在很多地方 xff0c 比如init函数 xff0c 当包被导入的时候只会被执行一次 实现单例模式有很多种方式 xff0c 这里给出几种简单的实现 xff1a 互斥锁 对全局共享变量加锁 xff0c 如果该变量不是
  • go面试题

    1 json包在使用的时候 xff0c 结构体里的变量不加tag能不能正常转成json里的字段 xff1f 如果变量首字母小写 xff0c 则为private 无论如何不能转 xff0c 因为取不到反射信息 如果变量首字母大写 xff0c
  • golang windows弹窗功能实现

    代码示例 span class token keyword package span main span class token keyword import span span class token punctuation span s
  • golang获取windows系统有线活跃网卡及IP配置

    代码 span class token keyword package span network span class token keyword import span span class token punctuation span
  • !!!Chapter 2 The Physical Layer

    2 1 The Theoretical Basis for Data Communication Fourier Analysis Any reasonably behaved periodic function g t with peri
  • 启动golang项目编译的exe可执行文件获取windows管理员权限(UAC)

    背景 xff1a go代码启动以后里面涉及到修改ip地址等操作 xff0c 需要管理员权限 打包好的exe文件双击执行默认是没有管理员权限的 xff0c 那么修改ip就会提示需要管理员权限 解决方法1 xff1a 右键以管理员权限运行exe
  • k8s外部访问pod内部容器的端口-NodePort

    一 如何从外部网络访问 Kubernetes的Pod IP和Cluster IP都只能在集群内部访问 xff0c 而我们通常需要从外部网络上访问集群中的某些服务 xff0c Kubernetes提供了下述几种方式来为集群提供外部流量入口 二
  • python断点下载文件

    使用pytohn编码实现文件的断点下载 span class token keyword import span os span class token keyword import span json span class token k
  • 异常检测(1)—初识异常检测

    1 概念 异常一般是指与标准值 xff08 预期值 xff09 有偏离的样本点 xff0c 也就是跟绝大部分数据 长的不一样 异常往往是 有价值 的事情 xff0c 我们对异常的成因感兴趣 2 类别 有监督 xff1a 数据集有标签无监督
  • 【git】在GitHub上下载历史版本

    GitHub上的项目很多都是从简单到复杂 xff0c 一点点迭代的 当我们需要看懂别人的代码时 xff0c 按照别人commit的历史版本一步一步跟踪 xff0c 或许是个好办法 这时候我们就要用到下载历史版本功能了 1 git clone
  • 实时操作系统UCOS学习笔记1----UCOSII简介

    前面我们所有的实验都是跑的裸机程序 xff08 裸奔 xff09 xff0c 从本章开始 xff0c 我们开始介绍UCOSII xff08 实时多任务操作系统内核 xff09 UCOSII简介 UCOSII的前身是UCOS xff0c 最早
  • 欢聚时代YY/测试实习面试

    去到YY大楼 xff0c 虽然在番禺但是附近很多楼在施工中了 大楼就在万达后面 前台登记 xff0c 小姐姐会让你出示邀请邮件 xff0c 然后直接上去就行了 达到楼层 xff0c 二维码签到 然后找地方坐一下等待面试 一轮是技术面 xff
  • 基于卡尔曼滤波的气压计高度解算

    ax ay az为归一化的加速度数据 1代表重力加速度 gx gy gz 为加速度数据 单位rad s altitude为气压计测量得到的海拔数据 欧拉角 float pitch roll yaw 世界坐标系下机体加速度 float ax
  • Kali安装Xfce4

    Kali安装Xface4 一 配置kali源并更新二 解决报错1 签名无效2 依赖报错 三 安装xfce4 一 配置kali源并更新 此处使用的是gedit编辑器 xff0c gedit etc apt sources list xff0c
  • 串口转WIFI的工作方式理解

    串口无线 AP xff08 COM AP xff09 串口无线 STA xff08 COM STA xff09 和 串口无线 AP 43 STA xff08 COM AP 43 STA xff09 3 个模式 串口WIFI模块是基于Uart
  • 典型环节的频率特性(建议收藏)

    自控笔记 5 3典型环节频率特性 控制系统种类繁多 xff0c 传递函数复杂 xff0c 但任何形式的传递函数都是由有限的典型环节组成 因此 xff0c 掌握典型环节的频率特性是使用频域法分析系统的基础 如下表所示 xff0c 构成系统的最
  • 【WINAPI】CreateSemaphore_信号量

    WINAPI CreateSemaphore 信号量 1 注册信号量函数1 1 参数1 2 返回值 2 释放信号量函数2 1 参数2 2 返回值 3 WaitForSingleObject3 2 参数3 3 返回值 4 例子4 1 运行结果