none
关于semaphore 的问题 RRS feed

  • 问题

  • #include <windows.h> #include <stdio.h> #define MAX_SEM_COUNT 10 #define THREADCOUNT 12 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 ghSemaphore = CreateSemaphore( NULL, // default security attributes MAX_SEM_COUNT, // initial count MAX_SEM_COUNT, // maximum count NULL); // unnamed semaphoreif (ghSemaphore == NULL) { printf("CreateSemaphore error: %d\n", GetLastError()); return 1; } // Create worker threadsfor( 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 identifierif( 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 handlesfor( i=0; i < THREADCOUNT; i++ ) CloseHandle(aThread[i]); 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 finishedif (!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; }

     

    这是MSDN中的示例,信号量的最大值设定为10。我的理解是WaitForSingleObject(ghSemaphore, 0L)语句只有在成功运行了10个线程时,信号量才变为nonsignal状态,此时函数返回值才能为WAIT_TIMEOUT。

    但是运行结果不是这样的,实在无法理解。请各位点拨了,不胜感谢!

    2013年1月28日 9:25

答案

  • WaitForSingleObject的第二个参数设置为0,则WaitForSingleObject总是立即返回,所在的线程不会进入等待状态。

    若设为非零值,则非零值代表了最长的等待时间。

    若设为INFINITE,则该函数只有在对象变为有信号时才返回。


    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月29日 6:21
    版主
  • 你把

    DWORD WINAPI ThreadProc( LPVOID lpParam )
    {

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

        DWORD dwWaitResult;
        BOOL bContinue=TRUE;

    改成

      volatile  DWORD dwWaitResult;
      volatile   BOOL bContinue=TRUE;


    麻烦把正确答案设为解答。

    2013年1月31日 2:21
    版主

全部回复

  • 0太短了吧

    你用20试试


    新浪微博http://weibo.com/xianglitian,欢迎围观

    2013年1月29日 5:28
  • 能否告知你的实际运行结果是什么样的?

    是不是有的线程已经ReleaseSemaphore了?


    麻烦把正确答案设为解答。

    2013年1月29日 6:19
    版主
  • WaitForSingleObject的第二个参数设置为0,则WaitForSingleObject总是立即返回,所在的线程不会进入等待状态。

    若设为非零值,则非零值代表了最长的等待时间。

    若设为INFINITE,则该函数只有在对象变为有信号时才返回。


    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月29日 6:21
    版主
  • Thread 5444: wait succeeded
    Thread 2864: wait succeeded
    Thread 5436: wait succeeded
    Thread 4488: wait succeeded
    Thread 5000: wait succeeded
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait timed out
    Thread 5604: wait succeeded
    Thread 5172: wait succeeded
    Thread 5448: wait succeeded
    Thread 4328: wait succeeded
    Thread 4284: wait timed out
    Thread 4284: wait succeeded
    Thread 3080: wait succeeded
    Thread 5968: wait succeeded
    请按任意键继续. . .

    上面是运行结果,请解释程序执行的动态过程,谢谢。

    2013年1月29日 12:57
  •  volatile  DWORD dwWaitResult;
      volatile   BOOL bContinue=TRUE;

    麻烦把正确答案设为解答。

    2013年1月30日 10:04
    版主
  • 我的理解是先有10个线程成功执行,然后后来的线程才需要等待啊。

    2013年1月30日 15:50
  • 你把

    DWORD WINAPI ThreadProc( LPVOID lpParam )
    {

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

        DWORD dwWaitResult;
        BOOL bContinue=TRUE;

    改成

      volatile  DWORD dwWaitResult;
      volatile   BOOL bContinue=TRUE;


    麻烦把正确答案设为解答。

    2013年1月31日 2:21
    版主