代码改变世界

Semaphore同步

2012-12-15 19:27  kennyMc  阅读(399)  评论(0编辑  收藏  举报

信号量和事件内核对象一样,不会记录当前拥有资源的线程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和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。