当前位置:首页 > 芯闻号 > 充电吧
[导读] 1 BOOL ReleaseSemaphore( 2  HANDLE hSemaphore, // 信号量句柄 3  LONG lReleaseCount, // 计数递增数量 4  LPLONG 

 

1 BOOL ReleaseSemaphore(
2  HANDLE hSemaphore, // 信号量句柄
3  LONG lReleaseCount, // 计数递增数量
4  LPLONG lpPreviousCount // 先前计数
5 ); 
6 
7

 

 

C++信号量Semaphore和MFC中的CSemaphore类使用

信号量(Semaphore )内核对象对线程的同步方式与前面几种方法不同,它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最 大线程数目。

在用CreateSemaphore () 创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最 大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1 ,只要当前可用资源计数是大于0 的,就可以发出信号量信号。但是当前可用计数减小 到0 时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离 开的同时通过ReleaseSemaphore ()函数将当前可用资源计数加1 。在任何时候当前可用资源计数决不可能大于最大资源计数。
  信号量是通过计数来对线程访问资源进行控制的,而实际上信号量确实也被称作Dijkstra 计数器。
  使用信号量内核对象进行线程同步主要会用到CreateSemaphore、OpenSemaphore、 ReleaseSemaphore、WaitForSingleObject和WaitForMultipleObjects等函数。CreateSemaphore ()用来创建一个信号量内核对象,其函数原型为:

 

 

HANDLE CreateSemaphore(
 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
 LONG lInitialCount, // 初始计数
 LONG lMaximumCount, // 最大计数
 LPCTSTR lpName // 对象名指针
);

 

参数lMaximumCount 是一个有符号32 位值,定义了允许的最大资源计数,最大取值不能超过4294967295 。lpName 参数可以为创建的 信号量定义一个名字,由于其创建的是一个内核对象,因此在其他进程中可以通过该名字而得到此信号量。OpenSemaphore ()函数即可用来根据信号 量名打开在其他进程中创建的信号量,函数原型如下:

1 HANDLE OpenSemaphore(
2  DWORD dwDesiredAccess, // 访问标志
3  BOOL bInheritHandle, // 继承标志
4  LPCTSTR lpName // 信号量名
5 );

 

  在线程离开对共享资源的处理时,必须通过ReleaseSemaphore ()来增加当前可用资源计数。否则将会出现当前正在处理共享资源的实际线程数并 没有达到要限制的数值,而其他线程却因为当前可用资源计数为0 而仍无法进入的情况。ReleaseSemaphore ()的函数原型为:     该函数将lReleaseCount 中的值添加给信号量的当前资源计数,一般将lReleaseCount 设置为1 ,如果需要也可以设置其他的值。 WaitForSingleObject ()和WaitForMultipleObjects ()主要用在试图进入共享资源的线程函数入口处,主要用来判 断信号量的当前可用资源计数是否允许本线程的进入。只有在当前可用资源计数值大于0 时,被监视的信号量内核对象才会得到通知。
  信号量的使用特点使其更适用于对Socket (套接字)程序中线程的同步。例如,网络上的HTTP 服务器要对同一时间内访问同一页面的用户数加以限制,这 时可以为每一个用户对服务器的页面请求设置一个线程,而页面则是待保护的共享资源,通过使用信号量对线程的同步作用可以确保在任一时刻无论有多少用户对某 一页面进行访问,只有不大于设定的最大用户数目的线程能够进行访问,而其他的访问企图则被挂起,只有在有用户退出对此页面的访问后才有可能进入。下面给出 的示例代码即展示了类似的处理过程:

#include#include#includeusing namespace std;

 

HANDLE hSemaphore;

UINT __stdcall Add(LPVOID lParam)

{

    WaitForSingleObject(hSemaphore, INFINITE);

    for (int i = 0; i<10;i++ )

    {

       arr[i]=i;//0-9

    }

    for (int i = 0;i < 10; i++)

    {

       cout<<arr[i]<<" ";

    }

    cout<<endl;

    ReleaseSemaphore(hSemaphore, 1, NULL); 

//信号量加1。如果不释放。因为当前可用为1个,且被占用了,那么Add2不会执行

    return 1;

}

UINT __stdcall Add2(LPVOID lParam)

{

    WaitForSingleObject(hSemaphore, INFINITE);

    for (int i = 0; i<100 ;i++)

    {

       arr [i] = i+100;//10`1

    }

    for (int i = 0;i < 10; i++)

    {

       cout<<arr[i]<<" ";

    }

    cout<<endl;

    ReleaseSemaphore(hSemaphore, 1, NULL); 

    return 1;

}

int main()

{

 

 

    hSemaphore =CreateSemaphore(NULL,1,2,"");

//创建无名信号量,初始2个,可用1个

    hUp=(HANDLE)_beginthreadex(NULL, 0, Add, NULL, NULL, 0);

    hUp=(HANDLE)_beginthreadex(NULL, 0, Add2, NULL, NULL, 0);

    Sleep(5000);

}

 

 

在MFC 中,通过CSemaphore 类对信号量作了表述。该类只具有一个构造函数,可以构造一个信号量对象,并对初始资源计数、最大资源计数、对象名和安全属性等进行初始化,其原型如下:
CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );
  在构造了CSemaphore 类对象后,任何一个访问受保护共享资源的线程都必须通过CSemaphore 从父类CSyncObject 类继承得到的 Lock ()和UnLock ()成员函数来访问或释放CSemaphore 对象。与前面介绍的几种通过MFC 类保持线程同步的方法类似,通过 CSemaphore 类也可以将前面的线程同步代码进行改写,这两种使用信号量的线程同步方法无论是在实现原理上还是从实现结果上都是完全一致的。下面给出经MFC 改写后的信号量线程同步代码:

CSemaphore g_clsSemaphore(1, 2);

MFC中不用WaitForSingleObject。

g_clsSemaphore.Lock计数器减1,g_clsSemaphore.Unlock计数器加1

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

其实在 c++语言里面const修饰的才算是一个真正的常量,在 c 语言中 const 可以说是个“冒牌货”。为什么会这样?其实是 c++ 编译器对 const 进行了加强,当 c++ 编译器遇到常量声明时,不会像 c...

关键字: c++ C语言 const

返回函数的引用去初始化一个新的引用这个和前面一样,都是不会产生副本,但是现在是用返回值去初始化一个引用声明c,也就是说这时候变成了变量temp的别名,在c的生命周期内temp是一直有效的,这样做完全可以。

关键字: c++ 返回值 引用声明

摘要:随着我国智能电网的快速发展,传统采集设备已无法完全满足当前需求。配电台区是营销与生产的交汇点,传统模式下,营销与生产双方需要在台区侧分别安装集中器和配变终端(TTU)两种设备,但仍存在诸多问题。在此背景下,融合了I...

关键字: 能源控制器 信号量 死锁

衰落效应是影响无线通信质量的主要因素之一。其中的快衰落深度可达30~40dB,如果想利用加大发射功率、增加天线尺寸和高度等方法来克服这种深衰落是不现实的,而且会造成对其它电台的干扰。而采用分集方法即在若干个支路上接收相互...

关键字: 分集技术 信号量 衰减

C++是一种面向对象的高级程序设计语言,是C语言的超集。

关键字: c++ C语言

摘要:阐述了一种基于GPRS和嵌入式Linux的远程图像监控系统设计和实现方法。该系统主要由嵌入式视频采集终端 和监控中心服务器组成。其中,嵌入式视频采集终端主要由摄像头视频采集模块、ARM模块、SIM900模块组成,监...

关键字: 通用分组无线业务 实时图像采集 多线程 信号量

FreeRTOS的信号量包括二进制信号量、计数信号量、互斥信号量(以后简称互斥量)和递归互斥信号量(以后简称递归互斥量)。

关键字: FreeRTOS 信号量分析 信号量

分析:这是Adobe 公司2007 年校园招聘的最新笔试题。这道题除了考察应聘者的C++ 基本功底外,还能考察反应能力,是一道很好的题目。 在Java 中定义了关键字final ,被final 修饰的

关键字: c++ class

泛型算法中的定制操作很多算法都会比较输入序列中的元素,通过定制比较动作,可以控制算法按照编程者的意图工作。本文以string排序为例进行说明,首先是缺省的排序动作: vector v{"This","

关键字: c++

为什么是lambda?讲了这么多天的lambda表达式,有一个很基本的问题没有回答:为什么叫lambda表达式呢?首先这个lambda就是罗马字母λ,lambda表达式即λ表达式。数学上有一个概念叫λ

关键字: c++
关闭
关闭