您的位置:首页 > 其它

线程同步——内核对象实现线程同步——信号量

2014-08-16 11:06 381 查看
/*

信号量内核对象
信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量。
一个最大资源计数和一个当前资源计数。
信号量规则如下:
如果当前资源计数大于0,那么信号量处于触发状态。
如果当前资源计数等于0,那么信号量处于未触发状态。
系统绝不会让当前资源计数变为负数。
当前资源计数绝不会大于最大资源计数。

下面我们看一下信号量的创建函数
HANDLE  CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCSTR lpName );
第一、四个参数同其他内核对象一样,就不过多介绍了。
第三个参数lInitialCount为当前资源计数,第四个参数lMaximumCount为最大资源计数

线程通过调用ReleaseSemaphore,来增加当前资源计数。
下面看ReleaseSemaphore函数:

BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount ) ;
第一个参数hSemaphore,为信号量句柄,第二个参数lReleaseCount为增加资源数
第三个参数lpPreviousCount为返回当前资源计数,一般传入 NULL。

关于信号量需要注意的是,在递减当前资源计数时是以原子方式进行的。
但是递减完后,其它线程便可以访问资源,在这个时候先前线程也许并未结束,
所以信号量并不互斥,主要用于控制访问次数或者创建的线程数。

下面我们看一下使用步骤:

1)
//定义一个信号量
HANDLE g_hSemaphore  ;
2)
//创建一个信号量内核对象
g_hSemaphore = CreateSemaphore(NULL,0,5,NULL);
3)
//增加信号量当前资源数
ReleaseSemaphore(g_hSemaphore,5,NULL);
4)
//在线程函数中调用
DWORD WINAPI ThreadFunOne(PVOID pvParam)
{
while(1)
{
WaitForSingleObject(g_hSemaphore,INFINITE);
g_x++;
cout<<"我是ThreadFunOne:"<<g_x<<endl;
}
return 0;
}

*/

#include "windows.h"
#include "iostream"
using namespace std;
long g_x = 0 ;

//定义一个信号量
HANDLE g_hSemaphore  ;
//定义线程函数1
DWORD WINAPI ThreadFunOne(PVOID pvParam) ;

//定义线程函数2
DWORD WINAPI ThreadFunTwo(PVOID pvParam);

int main()
{

//创建一个信号量内核对象
g_hSemaphore = CreateSemaphore(NULL,0,5,NULL);

//增加信号量当前资源数
ReleaseSemaphore(g_hSemaphore,5,NULL);

//创建线程1
HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);
CloseHandle(hThreadOne);

//创建线程2
HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);
CloseHandle(hThreadTwo);

getchar();
cout<<g_x<<endl;
return 0 ;
}

DWORD WINAPI ThreadFunOne(PVOID pvParam)
{
while(1)
{
WaitForSingleObject(g_hSemaphore,INFINITE);
g_x++;
cout<<"我是ThreadFunOne:"<<g_x<<endl;
}
return 0;
}

DWORD WINAPI ThreadFunTwo(PVOID pvParam)
{
while (1)
{
WaitForSingleObject(g_hSemaphore,INFINITE);
g_x++;
cout<<"我是ThreadFunTwo:"<<g_x<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: