windows多线程(八) 信号量Semaphore
如果你看到了这里,我就认为你已经对掌握了有关关键段 CriticalSection、互斥量Mutex和事件Event有关的内容,所以最基本的东西就不再介绍了。如果没有掌握上面说的内容,可以看这里:
一、信号量相关函数说明
(一) 创建信号量CreateSemaphore
1.函数原型
HANDLE WINAPI CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
_In_ LONG lInitialCount,
_In_ LONG lMaximumCount,
_In_opt_ LPCWSTR lpName
);
2.参数说明
第一个参数
lpSemaphoreAttributes,表示安全属性。如果是NULL,就表示使用默认属性。第二个参数
lInitialCount,信号量的初始数值,必须大于或等于0,并且小于或等于lMaximumCount第三个参数
lMaximumCount,信号量的最大值,即最大并发数。第四个参数
lpName,信号量的名字,是一个字符串,任何线程(或进程)都可以根据这一名称引用到这个信号量,这个值可以是NULL,表示产生一个匿名信号量。返回值: 如果成功就返回一个handle,否则传回NULL。
(二) 打开信号量OpenSemaphore
1.函数原型
HANDLE WINAPI OpenSemaphore(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCSTR lpName
);
2.参数说明
第一个参数
dwDesiredAccess,表示访问权限,一般传入SEMAPHORE_ALL_ACCESS。第二个参数
bInheritHandle,表示信号量句柄继承性,一般传入True。第三个参数
lpName,需要打开的信号量的名称。返回值: 如果成功就返回信号量handle,否则传回NULL。
(三) 信号量解除锁定ReleaseSemaphore
这个函数功能是实现信号量计数器增加一个值,该值通常是1,但不会超过创建信号量时指定的lMaximumCount
1.函数原型
BOOL WINAPI ReleaseSemaphore(
_In_ HANDLE hSemaphore,
_In_ LONG lReleaseCount,
_Out_opt_ LPLONG lpPreviousCount
);
2.参数说明
第一个参数
hSemaphore,信号量的句柄。第二个参数
lReleaseCount,表示信号量值增加的个数,必须大于0且不超过最大资源数,一般为1。第三个参数
lpPreviousCount,传出先前信号量的计数值,设置为NULL表示不需要传出。返回值: 如果成功就返回True,否则传回False。
(四) 关闭信号量
由于信号量是一个内核对象,关闭时直接调用CloseHandle()就可以了。
二、实例
使用信号量同样可以实现线程的同步,实现每个线程按顺序依次给全局资源加一,代码如下:
// 信号量演示
#include<iostream>
#include <windows.h>
using namespace std;
const int THREAD_NUM = 10;
int g_Num = 0;
CRITICAL_SECTION g_csVar; //创建关键段cs
HANDLE g_ThreadSema; //创建内核对象,用来初始化信号量
DWORD WINAPI Func(LPVOID);
int main()
{
InitializeCriticalSection(&g_csVar);
g_ThreadSema = CreateSemaphore(NULL, 0, 1, NULL); //创建匿名信号量,初始资源为零,最大并发数为1,
HANDLE handle[THREAD_NUM];
DWORD ThreadId[THREAD_NUM];
int i = 0;
while (i < THREAD_NUM)
{
handle[i] = CreateThread(NULL, 0, Func, &i, 0, &ThreadId[i]);
WaitForSingleObject(g_ThreadSema, INFINITE); //等待信号量资源数>0
i++;
}
WaitForMultipleObjects(THREAD_NUM, handle, true, INFINITE);
CloseHandle(g_ThreadSema); //销毁信号量
DeleteCriticalSection(&g_csVar);//销毁关键段cs
for (i = 0; i < THREAD_NUM; i++)
{
CloseHandle(handle[i]);
}
return 0;
}
DWORD WINAPI Func(LPVOID p)
{
int nThreadNum = *(int*)p;
EnterCriticalSection(&g_csVar);
cout << "线程编号为: " << nThreadNum << " 全局资源值为:" << ++g_Num << endl;
LeaveCriticalSection(&g_csVar);
ReleaseSemaphore(g_ThreadSema, 1, NULL); //信号量资源数加一
return 0;
}
运行结果如下所示:

windows多线程(八) 信号量Semaphore的更多相关文章
- windows多线程同步--信号量
推荐参考博客:秒杀多线程第八篇 经典线程同步 信号量Semaphore 首先先介绍和windows信号量有关的两个API:创建信号量.释放信号量 HANDLE WINAPI CreateSem ...
- windows核心编程-信号量(semaphore)
线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了互斥器线程同步-----windows核心编程-互斥器(Mutexes),这章我来介绍一下信号量(semaphore)线程同步. ...
- 多线程相关------信号量Semaphore
Semaphore用于对资源进行计数.允许一定数量的线程同时访问该资源.可以用于进程间同步 相关函数 CreateSemaphore 创建或打开一个信号量对象 HANDLE WINAPI Create ...
- 总结windows多线程同步互斥
windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...
- windows多线程同步互斥--总结
我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...
- 秒杀多线程第八篇 经典线程同步 信号量Semaphore
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <且不超过最大资源数量. 第三个參数能够用来传出先前的资源计数,设为NULL表示不须要传出. 注意:当 ...
- 转---秒杀多线程第八篇 经典线程同步 信号量Semaphore
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
- 多线程面试题系列(8):经典线程同步 信号量Semaphore
前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore常用有三个函数 ...
- C++多线程同步之Semaphore(信号量)
一.线程间同步的几种方式 从上篇博文中可以发现,当多个线程对同一资源进行使用时,会产生“争夺”的情况,为了避免这种情况的产生,也就出现了线程间的同步这个技术.线程间的同步有多种方式,在接下来的博文中我 ...
随机推荐
- SpringCloud-容错处理Hystrix熔断器(五)
前言:微服务架构应用的特点就是多服务,而服务层之间通过网络进行通信,从而支撑起整个应用系统,所以,各个微服务之间不可避免的存在耦合依赖关系.但任何的服务应用实例都不可能永远的健康或网络不可能永远的都相 ...
- springmvc pager-taglib 分页,bootstrap样式
注意: 嵌入到项目中时必须以带参形式访问: http://localhost:8081/DETECT-X/showConnLogsByPager.action?pageSize=5&pager ...
- Form,选择并转移导航菜单
1.代码实例 <!DOCTYPE html> <html> <head> <title>选择并转移导航菜单</title> <meta ...
- 【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!
写在前面 随着前端领域的发展和社会化分工的需要,继前端攻城湿之后,又一重要岗位横空出世——重构攻城湿!所谓的重构攻城湿,他们的一大特点之一,就是精通CSS配置文件的编写...前端攻城湿跟重构攻城湿是一 ...
- 搭建OpenSTF+Jenkins持续集成环境的协同开发
最近在研究如何将OpenSTF与Jenkins进行协同开发,刚刚爬梯子看了些资料,赶紧记录下来. 转载请注明出处:https://www.cnblogs.com/v88v/p/10405338.htm ...
- 统计学习方法c++实现之二 k近邻法
统计学习方法c++实现之二 k近邻算法 前言 k近邻算法可以说概念上很简单,即:"给定一个训练数据集,对新的输入实例,在训练数据集中找到与这个实例最邻近的k个实例,这k个实例的多数属于某个类 ...
- C#_Switch语句的内部实现
Switch的C#内部实现 https://www.cnblogs.com/Interkey/p/3730432.html 在IL汇编语言中的Switch指令 -- 按照标号来进行跳转(和goto语句 ...
- Arthas Alibaba 开源 Java 诊断工具
Arthas 用户文档 English Docs Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,A ...
- 曾经的华为C面试题,一点就通
学习编程可以锻炼你的思维,帮助你更好地思考,创建一种我认为在各领域都非常有用的思维方式. 比尔盖茨 曾经的华为C面试题,一点就通 [问题区] 有两个变量x和y, x=10; y = 2 ...
- 将jira添加至开机自启动
东北证券网金部jira项目管理系统,经常莫名挂掉,于是乎将jira服务加入开机自启动. jira.sh脚本代码如下: #!/bin/sh # chkconfig: # description:jira ...