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

第一个参数:安全属性,如果为NULL则是默认安全属性
第二个参数:信号量的初始值,要>=0且<=第三个参数
第三个参数:信号量的最大值
第四个参数:信号量的名称
返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄

使用方法:
1、创建一个信号量:CreateSemaphore;
2、打开一个已经存在的信号量:OpenSemaphore;
3、获得信号量的一个占有权:WaitForSingleObject、WaitForMultipleObjects 等一类等待的函数……(可能造成阻塞);
4、释放信号量的占有权:ReleaseSemaphore;
5、关闭信号量:CloseHandle;

※ 命名标准:Semaphores 可以跨进程使用,所以其名称对整个系统而言是全局的,所以命名不要过于普通,类似:Semaphore、Object 等。
最好想一些独一无二的名字等!

固有特点(优点+缺点):
1、是一个系统核心对象,所以有安全描述指针,用完了要 CloseHandle 关闭句柄,这些是内核对象的共同特征;
2、因为是核心对象,所以执行速度稍慢(当然只是相比较而言);
3、因为是核心对象,而且可以命名,所以可以跨进程使用;
4、Semaphore 使用正确的情况下不会发生死锁;
5、在“等待”一个 信号量 的时候,可以指定“结束等待”的时间长度;
6、非排他性的占有,跟 Critical Sections 和 Mutex 不同,这两种而言是排他性占有,
即:同一时间内只能有单一线程获得目标并拥有操作的权利,而 Semaphores 则不是这样,
同一时间内可以有多个线程获得目标并操作!

信号量没有线程所有权属性,即一个线程获得某个信号量后,在他释放该信号量之前,他不能再次进入信号量保护的区域

信号量的使用规则:

1. 如果当前资源计数大于0,那么信号量处于触发状态;

2. 如果当前资源计数等于0,那么信号量处于未触发状态;那么系统会让调用线程进入等待状态。

CreateSemaphore(NULL,0,1,NULL); 当第二个参数为0时,调用线程就会进入等待状态

3. 系统绝对不会让当前资源计数变为负数;

4. 当前资源计数绝对不会大于最大资源计数。

#include <iostream>
#include <windows.h>
using namespace std; const int g_Number = ;
DWORD WINAPI ThreadProc1(__in LPVOID lpParameter);
DWORD WINAPI ThreadProc2(__in LPVOID lpParameter);
DWORD WINAPI ThreadProc3(__in LPVOID lpParameter); HANDLE hSemp1,hSemp2,hSemp3; int main()
{
hSemp1 = CreateSemaphore(NULL,,,NULL);
hSemp2 = CreateSemaphore( NULL,,,NULL);
hSemp3 = CreateSemaphore(NULL,,,NULL); HANDLE hThread[ g_Number ] = {};
int first = , second = , third = ;
hThread[ ] = CreateThread(NULL,,ThreadProc1,(LPVOID)first,,NULL);
hThread[ ] = CreateThread(NULL,,ThreadProc2,(LPVOID)second,,NULL);
hThread[ ] = CreateThread(NULL,,ThreadProc3,(LPVOID)third,,NULL); WaitForMultipleObjects(g_Number,hThread,TRUE,INFINITE);
CloseHandle( hThread[] );
CloseHandle( hThread[] );
CloseHandle( hThread[] ); CloseHandle( hSemp1 );
CloseHandle( hSemp2 );
CloseHandle( hSemp3 );
return ;
} DWORD WINAPI ThreadProc1(__in LPVOID lpParameter)
{
WaitForSingleObject(hSemp1, INFINITE);//等待信号量
cout<<(int)lpParameter<<endl;
ReleaseSemaphore(hSemp1,,NULL);//释放信号量
return ;
} DWORD WINAPI ThreadProc2(__in LPVOID lpParameter)
{
WaitForSingleObject(hSemp2, INFINITE);//等待信号量
cout<<(int )lpParameter<<endl;
ReleaseSemaphore(hSemp2,,NULL);//释放信号量
return ;
} DWORD WINAPI ThreadProc3(__in LPVOID lpParameter)
{
WaitForSingleObject( hSemp3, INFINITE);//等待信号量
cout<<(int)lpParameter<<endl;
ReleaseSemaphore(hSemp3,,NULL);//释放信号量
return ;
}

window下线程同步之(Semaphores(信号量))的更多相关文章

  1. window下线程同步之(Event Objects(事件))

    Event 方式是最具弹性的同步机制,因为他的状态完全由你去决定,不会像 Mutex 和 Semaphores 的状态会由类似:WaitForSingleObject 一类的函数的调用而改变,所以你可 ...

  2. window下线程同步之(原子锁)

    原子锁:当多个线程同时对同一资源进行操作时,由于线程间资源的抢占,会导致操作的结果丢失或者不是我们预期的结果. 比如:线程A对一个变量进行var++操作,线程B也执行var++操作,当线程A执行var ...

  3. window下线程同步之(Mutex(互斥器) )

    使用方法: 1.创建一个互斥器:CreateMutex: 2.打开一个已经存在的互斥器:OpenMutex: 3.获得互斥器的拥有权:WaitForSingleObject.WaitForMultip ...

  4. window下线程同步之(Critical Sections(关键代码段、关键区域、临界区域)

    关键区域(CriticalSection) 临界区是为了确保同一个代码片段在同一时间只能被一个线程访问,与原子锁不同的是临界区是多条指令的锁定,而原子锁仅仅对单条操作指令有效;临界区和原子锁只能控制同 ...

  5. 改善C#程序的建议6:在线程同步中使用信号量

    原文:改善C#程序的建议6:在线程同步中使用信号量 所谓线程同步,就是多个线程之间在某个对象上执行等待(也可理解为锁定该对象),直到该对象被解除锁定.C#中对象的类型分为引用类型和值类型.CLR在这两 ...

  6. 编写高质量代码改善C#程序的157个建议——建议72:在线程同步中使用信号量

    建议72:在线程同步中使用信号量 所谓线程同步,就是多个线程在某个对象上执行等待(也可理解为锁定该对象),直到该对象被解除锁定.C#中对象的类型分为引用类型和值类型.CLR在这两种类型上的等待是不一样 ...

  7. [No000017D]改善C#程序的建议6:在线程同步中使用信号量

    所谓线程同步,就是多个线程之间在某个对象上执行等待(也可理解为锁定该对象),直到该对象被解除锁定.C#中对象的类型分为引用类型和值类型.CLR在这两种类型上的等待是不一样的.我们可以简单的理解为在CL ...

  8. Linux下线程同步的几种方法

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码.  1. 初始化锁 int pthrea ...

  9. 线程同步——用户模式下线程同步——Slim读写锁实现线程同步

    //Slim读/写锁实现线程同步 SRWlock 的目的和关键段相同:对同一资源进行保护,不让其它线程访问. 但是,与关键段不同的是,SRWlock允许我们区分哪些想要读取资源的线程(读取者线程) 和 ...

随机推荐

  1. 【树形DP】【P1351】 【NOIP2014D1T2】联合权值

    传送门 Description 无向连通图 \(G\) 有 \(n\) 个点, \(n-1\) 条边.点从 \(1\) 到 \(n\) 依次编号,编号为 \(i\) 的点的权值为 \(W_i\) ,每 ...

  2. Picture POJ - 1177 (线段树-扫描线)

    A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...

  3. mysql的cast()函数

    先来补个知识: decimal的用法: decimal(18,4)总长18位,包括1位小数点和4为小数,也就是说18-1-4=13整数位只有13位decimal(19,1)总长19位,17位整数,1位 ...

  4. tomcat 访问400 的一种情况

    tomcat 高版本对访问url做了较高的校验,如果url中包含特殊字符,tomcat会自动拦截,返回400错误.如果要包含特殊字符,需要事先进行转译. 我原来用的apache-tomcat-6.0. ...

  5. 第一篇 关于Android Studio的快捷键

    公司最近要培训Android的课程,但是发现现在官方网站上已经不提供了Eclipse ADT的下载了,都变成了Android Studio,可能是悲催了! 对于很多Eclipse转过来的同学,不适应的 ...

  6. 图论:Prufer编码

    BZOJ1211:使用prufer编码解决限定结点度数的树的计数问题 首先学习一下prufer编码是干什么用的 prufer编码可以与无根树形成一一对应的关系 一种无根树就对应了一种prufer编码 ...

  7. uva10766生成树计数(矩阵树定理)

    更正了我之前打错的地方,有边的话G[i][j]=-1; WA了好多次,中间要转成long double才行..这个晚点更新. #include<cstdio> #include<cs ...

  8. Bzoj1822 [JSOI2010]Frozen Nova 冷冻波

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1933  Solved: 608 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖 ...

  9. 【BZOJ】1299: [LLH邀请赛]巧克力棒

    [算法]博弈论 [题解]这道题不是典型的SG函数题了. 不把它当成游戏看待,那么这道题是在说n个石子堆,每次可以加入若干个或进行Nim游戏. 我们当前先手,则考虑构造必败态来获胜. 当前已加入的NIm ...

  10. Spring的使用优点

    spring事物配置,声明式事务管理和基于@Transactional注解的使用 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或者 ...