Semaphore Objects

原创 2015年07月09日 08:02:48
Semaphore Objects


A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. 
The count is decremented each time a thread completes a wait for the semaphore object and incremented each time a thread releases the semaphore. 
When the count reaches zero, no more threads can successfully wait for the semaphore object state to become signaled. 
The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.
Semaphone Object(信号量)是一个同步对象。Semaphone Object 包含一个从零到指定最大值的计数值。
当一个线程获取到Semaphone的权利时,计数值将减少1,当线程释放Semaphone权利时计数值增加一.当Semaphone Object的计数值到零时,任何线程都不能获取到Semaphone Object的权利.
当计数值大于零时,Semaphone Object标志着有信号,当Semaphone Object的计数值等于零时,标志着无信号。




The semaphore object is useful in controlling a shared resource that can support a limited number of users.
It acts as a gate that limits the number of threads sharing the resource to a specified maximum number. 
For example, an application might place a limit on the number of windows that it creates. 
It uses a semaphore with a maximum count equal to the window limit, decrementing the count whenever a window is created and incrementing it whenever a window is closed. 
The application specifies the semaphore object in call to one of the wait functions before each window is created. 
When the count is zero—indicating that the window limit has been reached—the wait function blocks execution of the window-creation code.


Semaphone Object在控制有限数量的线程来并发访问共享资源非常有用。Semaphone Object就像一个门卫,只运行指定最大数量的线程来并发访问共享资源。
例如:应用程序可以在Windows创建资源上做一个指定的最大限制。
  
A thread uses the CreateSemaphore or CreateSemaphoreEx function to create a semaphore object. 
The creating thread specifies the initial count and the maximum value of the count for the object. 
The initial count must be neither less than zero nor greater than the maximum value. 
The creating thread can also specify a name for the semaphore object.
Threads in other processes can open a handle to an existing semaphore object by specifying its name in a call to the OpenSemaphore function.
线程通过CreateSemaphore() 和CreateSemaphoreEx()来创建一个Semaphone Object.
创建线程将指定计数的一个初始化值和一个最大值。初始化值必须小于等于最大值。同时,线程也可以为Semaphone Object指定一个名字。
在其他进程中的任何线程都可以通过OpenSemaphore()函数传递一个名字参数到有名称的Semaphone Object 来获取该对象。
  
If more than one thread is waiting on a semaphore, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order.
External events such as kernel-mode APCs can change the wait order.
如果多个线程在等待同一个Semaphone Object,任意一个线程将被选中。不依赖于先进先出FIFL顺序。但是可以通过内核模式来改变排队的顺序。
Each time one of the wait functions returns because the state of a semaphore was set to signaled, the count of the semaphore is decreased by one.
The ReleaseSemaphore function increases a semaphore's count by a specified amount. The count can never be less than zero or greater than the maximum value.


wait等待函数返回时,Semaphone Object 的状态将被设置成有信号,同时计数值也被减少1.线程可以通过ReleaseSemaphore()函数来增加计数值。但是,计数值必须不能小于零,不能大于最大值。
The initial count of a semaphore is typically set to the maximum value. 
The count is then decremented from that level as the protected resource is consumed. 
Alternatively, you can create a semaphore with an initial count of zero to block access to the protected resource while the application is being initialized.
After initialization, you can use ReleaseSemaphore to increment the count to the maximum value.


通常情况下,初始化值被设置成最大值。当被保护资源消耗时,计数值被减小1.也可以把初始值设置成零,这样在应用程序初始化时,等待的线程就会被阻塞从而保护共享资源。
初始化后,线程必须通过ReleaseSemaphore()函数来增加1.
A thread that owns a mutex object can wait repeatedly for the same mutex object to become signaled without its execution becoming blocked.
A thread that waits repeatedly for the same semaphore object, however, decrements the semaphore's count each time a wait operation is completed; 
the thread is blocked when the count gets to zero.
Similarly, only the thread that owns a mutex can successfully call the ReleaseMutex function, though any thread can use ReleaseSemaphore to increase the count of a semaphore object.
注意:注意:当一个拥有Mutex Object(互斥量)的线程重复调用等待函数,Mutex Object 依旧有信号,并且不会发生阻塞,这样可以防止自锁。
但是,当一个拥有Semaphone Object对象重复调用等待函数时,当等待函数完成时,Semaphone Object的计数量将减少1.当同一线程多次调用同一个Semaphone Object时,当计数量为零时,就会发生阻塞。




A thread can decrement a semaphore's count more than once by repeatedly specifying the same semaphore object in calls to any of the wait functions. 
However, calling one of the multiple-object wait functions with an array that contains multiple handles of the same semaphore does not result in multiple decrements.


When you have finished using the semaphore object, call the CloseHandle function to close the handle. 
The semaphore object is destroyed when its last handle has been closed. 
Closing the handle does not affect the semaphore count; therefore, be sure to call ReleaseSemaphore before closing the handle or before the process terminates. 
Otherwise, pending wait operations will either time out or continue indefinitely, depending on whether a time-out value has been specified.
当结束使用Semaphone Object时,可以通过CloseHandle()来释放Semaphone Object.
关闭Semaphone Object时,并不影响Semaphone Object的计数量。所有,必须确保关闭Semaphone Object时通过ReleaseSemaphore()函数减少计数量。

否则在等待期间的其他线程将超时或者无限期持续等待。

例子:UsingSemaphoreObjects.cpp

#include <windows.h>
#include <stdio.h>

#define MAX_SEM_COUNT 5
#define THREADCOUNT 10

HANDLE ghSemaphore;

DWORD WINAPI ThreadProc( LPVOID );

int main( void )
{
    HANDLE aThread[THREADCOUNT];
    DWORD ThreadID;
    int i;

    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
	//创建一个信号量,初始值和最大值相等,这样就运行MAX_SEM_COUNT 线程同时访问共享资源。
	//信号量没有指定名称,这样其他进程中的线程就不能获取到该信号量
    ghSemaphore = CreateSemaphore( 
        NULL,           // default security attributes
        MAX_SEM_COUNT,  // initial count
        MAX_SEM_COUNT,  // maximum count
        NULL);          // unnamed semaphore

    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }

    // Create worker threads
	//创建线程数量大于信号的计数值,可以就有存在几个线程在其他线程访问完后才能访问该信号量,在此期间不能获取信号的线程将超时。
    for( i=0; i < THREADCOUNT; i++ )
    {
        aThread[i] = CreateThread( 
                     NULL,       // default security attributes
                     0,          // default stack size
                     (LPTHREAD_START_ROUTINE) ThreadProc, 
                     NULL,       // no thread function arguments
                     0,          // default creation flags
                     &ThreadID); // receive thread identifier

        if( aThread[i] == NULL )
        {
            printf("CreateThread error: %d\n", GetLastError());
            return 1;
        }
    }

    // Wait for all threads to terminate
	//等待所有的线程结束完成。
    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    // Close thread and semaphore handles

    for( i=0; i < THREADCOUNT; i++ )
        CloseHandle(aThread[i]);
	printf("=====================================: %d\n", GetCurrentThreadId());
	//当前主线程可以多次获取Metux Object,但是最大只能获取到MAX_SEM_COUNT 次数
	for(size_t t =0;t<MAX_SEM_COUNT*2;t++)
	{
			 // Try to enter the semaphore gate.

         DWORD dwWaitResult = WaitForSingleObject( 
            ghSemaphore,   // handle to semaphore
            0L);           // zero-second time-out interval
        switch (dwWaitResult) 
        { 
            // The semaphore object was signaled.
            case WAIT_OBJECT_0: 
				    printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
                break; 
			      // The semaphore was nonsignaled, so a time-out occurred.
            case WAIT_TIMEOUT: 
                printf("Thread %d: wait timed out\n", GetCurrentThreadId());
                break; 
		}
	}

    CloseHandle(ghSemaphore);

    return 0;
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{

    // lpParam not used in this example
    UNREFERENCED_PARAMETER(lpParam);

    DWORD dwWaitResult; 
    BOOL bContinue=TRUE;

    while(bContinue)
    {
        // Try to enter the semaphore gate.

        dwWaitResult = WaitForSingleObject( 
            ghSemaphore,   // handle to semaphore
            0L);           // zero-second time-out interval

        switch (dwWaitResult) 
        { 
            // The semaphore object was signaled.
            case WAIT_OBJECT_0: 
                // TODO: Perform task
                printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
                bContinue=FALSE;            

                // Simulate thread spending time on task
                Sleep(5);

                // Release the semaphore when task is finished

                if (!ReleaseSemaphore( 
                        ghSemaphore,  // handle to semaphore
                        1,            // increase count by one
                        NULL) )       // not interested in previous count
                {
                    printf("ReleaseSemaphore error: %d\n", GetLastError());
                }
                break; 

            // The semaphore was nonsignaled, so a time-out occurred.
            case WAIT_TIMEOUT: 
                printf("Thread %d: wait timed out\n", GetCurrentThreadId());
                break; 
        }
    }
    return TRUE;
}

运行结果:


相关文章推荐

基于SPOC的ucosii_Semaphore实验

  • 2012年10月09日 18:04
  • 7KB
  • 下载

Windows 7 安装 Rational Rose 启动报错:无法启动此程序,因为计算机中丢失 suite objects.dll。

安装完以后提示找不到 suite objects.dll: 经查找,该 dll 存在: 找不到的原因是,安装程序自动设置在 Path 中的环境变量有误: 把最后的 com...
  • g5dsk
  • g5dsk
  • 2011年09月06日 17:28
  • 11120

mutex和semaphore互斥程序实例

  • 2010年11月12日 12:56
  • 901B
  • 下载

Arc Objects10创建线要素图层

程序的运行环境为VS2010+ArcObjects10,代码完全使用C#。 创建线要素时要分别定义一个线对象和起止点对象,关键代码如下: IPolyline line = new Polylin...
  • jovon
  • jovon
  • 2014年03月18日 19:44
  • 1011

hardware_semaphore2.zip

  • 2015年05月11日 09:00
  • 111KB
  • 下载

Semaphore_TBOX_应用0_轻松开始

  • 2014年12月23日 08:47
  • 1.56MB
  • 下载

Java Objects Memory Structure

Update (December 18th, 2008): I've posted here an experimental library that implements Sizeof for J...

Semaphore的使用及其方法的使用

  • 2014年12月18日 22:20
  • 5KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Semaphore Objects
举报原因:
原因补充:

(最多只允许输入30个字)