Semaphore同步

本文探讨了信号量作为内核对象在多线程同步中的应用,阐述了其与事件的区别,通过代码实例展示了如何使用信号量实现线程间的同步与资源分配。重点分析了信号量资源数量对线程执行顺序的影响,以及不同参数设置下线程同步的差异。

信号量和事件内核对象一样,不会记录当前拥有资源的线程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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值