2014-02-08 106 views
0

所以我只是在學習C++互斥體,而且我正在關注MSDN上的大多數示例。爲什麼我會超時?我使用Sleep()將互斥量超時設置爲2000毫秒,「假」進程設置爲250毫秒。你可以看到它處理一些罰款,然後開始吹了....我知道如果我把互斥超時時間設置爲60000ms,它會很好,但爲什麼我只想要一個250ms的過程高?另外,它爲什麼從threadid#1跳到threadid#25?VC++ Mutex問題

謝謝! 埃裏克

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927(v=vs.85).aspx

int createMutex(char* mutexName) 
{ 

#define THREADCOUNT 25 

    HANDLE aThread[THREADCOUNT]; 
    DWORD ThreadID; 
    int i; 

    int ID[THREADCOUNT]; 

    // Create a mutex with no initial owner 

    ghMutex = CreateMutex(
     NULL,    // default security attributes 
     FALSE,    // initially not owned 
     (LPCWSTR)mutexName);    // unnamed mutex 

    if (ghMutex == NULL) 
    { 
     return 1; 
    } 

    // Create worker threads 
    for(i=0; i < THREADCOUNT; i++) 
    { 
     ID[i] = i +1; 
     aThread[i] = CreateThread( 
      NULL,  // default security attributes 
      0,   // default stack size 
      (LPTHREAD_START_ROUTINE) WriteToDatabase, 
      &ID[i],  // no thread function arguments 
      0,   // default creation flags 
      &ThreadID); // receive thread identifier 

     if(aThread[i] == NULL) 
     { 
      return 1; 
     } 
    } 

    // Wait for all threads to terminate 
    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE); 

    // Close thread and mutex handles 
    for(i=0; i < THREADCOUNT; i++) CloseHandle(aThread[i]); 

    CloseHandle(ghMutex); 

    return 0; 

} 

DWORD WINAPI WriteToDatabase(int *ID){ 

    int threadID = *ID; 

    char buffer[256]; 
    int MUTEX_TIMEOUT = 2000; 
    int FAKE_PROCESS_TIME_DELAY = 250; 

    DWORD dwWaitResult; 

    // Request ownership of mutex. 
    dwWaitResult = WaitForSingleObject( 
     ghMutex, // handle to mutex 
     MUTEX_TIMEOUT);  // time-out interval 

    sprintf(buffer, "NEW THREAD STARTED: #%d\n", threadID); 
    printf(buffer); 

    if(dwWaitResult == WAIT_OBJECT_0){ 

     // The thread got ownership of the mutex 
     sprintf(buffer, "DB WRITE STATED: #%d\n", threadID); 
     printf(buffer); 

     Sleep(FAKE_PROCESS_TIME_DELAY); //simulate a long running process (db process?) which creates a WAIT_TIMEOUT 

     sprintf(buffer, "DB WRITE COMPLETED: #%d\n", threadID); 
     printf(buffer); 

     dwCount++; 
     ReleaseMutex(ghMutex); 

     return TRUE; 
    }else{ 
     switch(dwWaitResult){ 
       case WAIT_ABANDONED: 
        sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "WAIT_ABANDONED", threadID); 
        break; 
       case WAIT_TIMEOUT: 
        sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "WAIT_TIMEOUT", threadID); 
        break; 
       default: 
        sprintf(buffer, "MUTEX ERROR [%s] #%d\n", "UNKNOWN", threadID); 
     } 

     printf(buffer); 
     MutexERRORs++; 

     //ReleaseMutex(ghMutex); 
     return FALSE; 
    }   

    return TRUE; 
} 

enter image description here

回答

1

您幾乎同時創建了25個線程,如果每個線程都需要〜250ms的互斥量,然後每個線程連續運行,所有線程處理的總時間將爲250ms * 25 = 6250ms。考慮到這一點,你的一些線程肯定會超時獲取互斥量,因爲你只等了2000ms。事實上,看起來像8個線程處理完畢後,其餘超時(自250ms * 8 = 2000ms以來應該不會令人意外)。至於線程#25在線程#1之後獲取互斥體,我不相信在等待與獲取互斥體方面有任何保證排序。多次運行它,每次運行時可能會得到不同的順序。

+0

銥星,我的印象是,超時是針對當前擁有互斥量的線程。你是說互斥隊列中的每個線程都有自己的超時計數器嗎? – kenyu73

+1

@ kenyu73您指定的超時時間是線程*調用WaitForSingleObject函數等待獲取互斥量的最長時間。如果它在那段時間沒有獲得它,它會返回'WAIT_TIMEOUT'。它對那個線程持有*互斥量沒有任何影響。 – Iridium

+0

這意味着如果數據不是時間敏感的,那麼WaitForSingleObject的大多數實現都希望使用INFINITE。 – kenyu73

1

只是無限或者您希望更多數量的替代MUTEX_TIMEOUT

由於操作系統管理它們,您無法知道哪個線程在特定時間工作。不要擔心thread_25可以工作得更早。如果您希望線程按創建順序運行,則應手動管理它們。

+0

對,我明白了。我正在尋找爲什麼或爲什麼不想這樣做的原因。爲什麼我沒有工作?如果將其設置爲無限且我有一個永不停止的掛起過程會發生什麼? – kenyu73

+1

因爲線程獲取互斥鎖時,睡眠時間爲250毫秒,其他線程正在憤怒地看着它。因爲它獲得了互斥體,並在其他線程正在捱餓時進入睡眠狀態。當互斥體得到釋放時,其他線程也會獲得它並睡眠。這種情況將繼續爲您的所有25個線程。其實你的代碼工作。等待線程完成他們的工作。 –