kenyu73
kenyu73

Reputation: 681

VC++ Mutex Issue

So I'm just learning about c++ mutexes and I'm following, for the most part, the examples on MSDN. Why am I getting timeouts? I have the mutex timeout set at 2000ms and the "fake" process set at 250ms using Sleep(). You can see it processes some fine, then starts blowing up.... I know if I up the mutex timeout to something like 60000ms, it'll be fine, but why would I want it that high for only a 250ms process? Also, why is it jumping from threadid #1 to threadid #25??

Thanks! Eric

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

Upvotes: 0

Views: 403

Answers (2)

Iridium
Iridium

Reputation: 23731

You're creating 25 threads at practically the same time, if each takes the mutex for ~250ms then with each thread running back-to-back the total time for all threads to process is going to be 250ms * 25 = 6250ms. With this in mind, some of your threads are sure to time-out acquiring the mutex because you're only waiting 2000ms. Indeed, it looks like after 8 threads have processed, the rest time-out (which should come as no surprise since 250ms * 8 = 2000ms).

As far as thread #25 acquiring the mutex after thread #1, I don't believe there's any guaranteed ordering with regards waiting vs. acquiring the mutex. Run it a number of times and you'll likely get a different order on each run.

Upvotes: 1

Mustafa Chelik
Mustafa Chelik

Reputation: 2184

Just replace MUTEX_TIMEOUT with INFINITE or a greater number you wish.

You won't know which thread will work at a certain time, since OS manages them. Don't worry that thread_25 works earlier. If you want threads run in order of creation, you should manage them manually.

Upvotes: 1

Related Questions