信号量和事件内核对象一样,不会记录当前拥有资源的线程ID,没有线程占有权一说,信号量靠资源数量来进行同步,可用资源量等于0,代表信号量未激活,大于0,信号量被激活,并且允许资源数量个线程进入。

#include <iostream>
#include <process.h>
#include <windows.h>
#include <string>
using std::cout;
using std::endl;
using std::string;const int num=2;
int count;
HANDLE _Semaphore;
unsigned __stdcall ThreadFun(void* par);int main()
{count=0;HANDLE handles[num];//创建一个初始资源0,最大并发1的信号量_Semaphore=CreateSemaphore(NULL,0,1,NULL);for(int i=0;i<num;++i){handles[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,0);//等待信号量可用资源数大于0(资源数大于0表示信号量处于触发状态)
        WaitForSingleObject(_Semaphore,INFINITE);}//等待所有线程执行完毕
    WaitForMultipleObjects(num,handles,TRUE,INFINITE);for(int i=0;i<num;++i)CloseHandle(handles[i]);//关系信号量
    CloseHandle(_Semaphore);system("PAUSE");return 0;
}
unsigned __stdcall ThreadFun(void* par)
{for(int i=0;i<10;++i)cout<<"cout:"<<++count<<endl;count=0;//释放一个资源,让信号量的资源数加1(注意:这里输出可能乱,只是为了观察ReleaseSemaphore结果)cout<<"ReleaseSemaphore:"<<ReleaseSemaphore(_Semaphore,1,NULL)<<endl;return 0;
}

如果我们将代码修改一下,一共有3个线程,并且信号量资源最大数为3,ReleaseSemaphore(_Semaphore,2,NULL)每次释放递增2个可用资源,那么结果就会不一样,第一个线程输出正常,然后递增2个可用资源,剩下2个线程就可以顺利执行,导致后面2个线程无法同步。

#include <iostream>
#include <process.h>
#include <windows.h>
#include <string>
using std::cout;
using std::endl;
using std::string;const int num=3;
int count;
HANDLE _Semaphore;
unsigned __stdcall ThreadFun(void* par);int main()
{count=0;HANDLE handles[num];//创建一个初始资源0,最大并发1的信号量_Semaphore=CreateSemaphore(NULL,0,3,NULL);for(int i=0;i<num;++i){handles[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,0);//等待信号量可用资源数大于0(资源数大于0表示信号量处于触发状态)
        WaitForSingleObject(_Semaphore,INFINITE);}//等待所有线程执行完毕
    WaitForMultipleObjects(num,handles,TRUE,INFINITE);for(int i=0;i<num;++i)CloseHandle(handles[i]);//关系信号量
    CloseHandle(_Semaphore);system("PAUSE");return 0;
}
unsigned __stdcall ThreadFun(void* par)
{for(int i=0;i<10;++i)cout<<"cout:"<<++count<<endl;count=0;//释放一个资源,让信号量的资源数加1(注意:这里输出可能乱,只是为了观察ReleaseSemaphore结果)cout<<"ReleaseSemaphore:"<<ReleaseSemaphore(_Semaphore,2,NULL)<<endl;return 0;
}

注意输出结果,后面2个线程同步失败

本文版权归kennyMc和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/kennyMc/archive/2012/12/15/2819620.html

Semaphore同步相关推荐

  1. Linux中的线程同步机制-futex

    Linux中的线程同步机制(一) -- Futex 引子 在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这 ...

  2. linux Futex同步机制

    Linux中的线程同步机制(一) -- Futex 引子 在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这 ...

  3. ACE入门---很好的文章

    转自:http://www.cnblogs.com/dubingsky/archive/2009/07/22/1528292.html ACE编译 1. 设置环境变量 在操作系统添加一个名为ACE_R ...

  4. Blocks与Dispatch Queue的使用

    2019独角兽企业重金招聘Python工程师标准>>> block是什么 block是一个C level的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似.用于回调函数的地 ...

  5. block 与 dispatch quene

    深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...

  6. 使用系统调用pipe建立一条管道线_【Linux系统】Linux进程间通信

    作者:Vamei 出处:http://www.cnblogs.com/vamei 我们在Linux信号基础中已经说明,信号可以看作一种粗糙的进程间通信(IPC, interprocess commun ...

  7. 操作系统和数据库专业单词

    操作系统 Operating system: 操作系统 Virtual machine: 虚拟机 Resource manager: 资源管理者 1.2 Vacuum tube: 真空管 Transi ...

  8. 嵌入式学习——周总结

    学习目标: 掌握进程.线程. 学习网络编程. 学习内容: 进程 1.进程的基本知识. 2.进程的相关命令:1.pstree 2.ps 3.kill 4.bg 5.fg . 3.虚拟地址与物理地址的概念 ...

  9. ACE的框架及其核心

    ACE设计框架和基础模块的关联 *一.案例描述 视频电警开发,是基于ACE框架上的一次重复开发,本文档拟对ACE框架做一个梳理,以期对他人进行基于ace的开发有所帮助. *二.系统安装 ACE的安装是 ...

最新文章

  1. 市场营销学python有用吗_1、熟悉Python编辑、开发和运行环境。
  2. YOLOP ONNXRuntime C++工程化记录
  3. 一个代码托管平台居然公开拒招中国人,谁给了你歧视中国程序员的勇气?
  4. 无外网情况下RPM方式安装MySQL5.6
  5. 前端埋点方法解析及优缺点分析
  6. Leetcode106 由中序序列和后序序列构建二叉树
  7. python解压文件(自用)
  8. 【转载】jQuery框架
  9. 如何创建C语言的项目
  10. 用差分法求解burger方程 matlab,偏微分方程数值解上机实验.doc
  11. 学习日记——W25Q64 FLASH—QSPI
  12. mp4转mp3,mp4转换成mp3方法步骤
  13. MATLAB程序中常见的语法错误,Matlab常见语法错误及解决方法
  14. 如何在水晶报表里显示图象?
  15. hp服务器不显示错误代码,惠普服务器开启不了
  16. 海王小姐姐教你微信如何三步实现多开,win7 win 8 win10都可用
  17. 一文教你看懂Fama-French三因子模型
  18. linux 查看 磁盘iops,linux – 磁盘IOPS和sar tps之间的关系
  19. react native 文本换行
  20. Cocos2dx 菜单项控件-Menu

热门文章

  1. Java+Selenium+sikuli script入门使用
  2. 学会python的基础操作题_第3章 Python基础-文件操作函数 文件操作 练习题
  3. python重命名异常_python异常处理
  4. 通过IDEA查看某个类的继承关系
  5. Qt IFW基本用法
  6. 华大 MCU 之四 使用问题记录
  7. Executor框架、ThreadPoolExecutor、3种常见的线程池
  8. 数据结构与算法 / UUID 和 GUID 区别和联系
  9. libwebsockets / vs2019 编译 libwebsockets 4.0 方法
  10. TCP/IP / 如何进行流量控制( flow control )?