• 其他语言



使用 Win32* 函数管理信号量
页面和feed选项
打印 | 通过电子邮件发送给朋友 | 联系支持中心
收藏此页
Digg此页 | 添加到您的del.icio.us帐号
给此页评分
论坛标签

搜索标签
 

挑战
应用 Win32* 函数创建信号量、等待对象并释放信号量。信号量是一个核心对象,拥有一个计数器,可用来管理大量有限的系统资源。将信号量视作整数变量,支持运行两个不可分割的运算。分别为 waitsignal。信号量用于确保任何时候某一资源仅能被一个正在执行的函数所用。它们可在多个执行中的函数和同步函数之间提供互斥信号量。信号量主要用以解决生产者/消费者同时读写的问题。

当计数值大于零时,信号量为有信号状态;当计数值为零时,信号量处于无信号状态。

解决方案使用内置函数: CreateSemaphore()、 OpenSemaphore()、 WaitForSingleObject()、 WaitForMultipleObjects()、 ReleaseSemaphore()、 以及 CloseHandle()。

在 Win32* 中,可以通过调用 CreateSemaphore() 创建一个信号量(如果已存在,可使用 OpenSemaphore() 。信号量的当前值代表当前可用的锁定(lock)数量。通过调用 Wait...() 函数(如 WaitForSingleObject() 或 WaitForMultipleObjects())中的任意函数可获得信号量锁定。如果没有一个线程拥有信号量,Wait...() 函数则立即返回。

如果信号量成功获得锁定,并不意味信号量拥有独占锁定。重复调用 Wait...() 函数将为每个调用获得一个新锁定。当信号量对象处于无信号状态时,所有可利用资源都正被其它线程使用。如果一个线程调用处于无信号状态的信号量中的 Wait...() 函数,这一线程则会被封锁,直至其中一个锁定释放。

与互斥体不同,此处不存在可由其它线程检测的状态,如“放弃等待”。要释放锁定,可调用 ReleaseSemaphore() 函数,此函数可增加计数器数值。任意线程都可调用这一函数来释放锁定。使用 CloseHandle() 函数可结束对信号量对象的处理。当最后一个线程结束处理时,信号量对象也随即消失。

以下代码段显示了如何创建信号量、等待多个对象以及释放信号量:


//start main function
HANDLE hSemaphore, hThread;

//create semaphore
hSemaphore = CreateSemaphore (NULL, // default security attributes
2, // initial count
2, //maximum count
NULL); // object name
if (hSemaphore == NULL)

{
printf ("Error creating the semaphore\n");
exit (1);
}
//create child threads
for (i=0; i<3; i++)
{
hThread=CreateThread(NULL,0,foo,(LPVOID)i,0,&dwThreadID);
if (hThread)
printf ("Thread launched successfully\n");
else
//print error message and exit (-1)
}

//wait until child threads have exited
DWORD dwCThd = WaitForMultipleObjects (3, //count of objects
hThread, //thread handle
TRUE, //wait for all
INFINITE); //time out interval
If (dwCThd != WAIT_OBJECT_0)
//Print error message and exit (-1)

//close handle for semaphore
CloseHandle (hSemaphore);
//close child thread handles
for (i=0; i<3; i++)
CloseHandle (hThread[i]);
//end of main function

/******
* function foo
******/
DWORD WINAPI foo (LPVOID num)
{
for( j = 0; j<3; j++)
{
//wait for single object
DWORD dwRes = WaitForSingleObject (hSemaphore, INFINITE);
If (dwRes == WAIT_OBJECT_0)
//acquired the semaphore
else
//print error
// do something
// release semaphore
Long lpPreviousCount;
ReleaseSemaphore (hSemaphore,
1, // count of the semaphore object
// is to be increased
&lpPreviousCount); //pointer to a 32-bit variable
// for the previous count of
// the semaphore
Sleep (1000);
}
return 0;
}


我们邀请您在本页 发表评论 (不受客服控制),或直接向我们的支持中心 提问.