Phylliida
Phylliida

Reputation: 4383

Why does using a semaphore in a seperate thread freeze up the program?

I had this problem, so I boiled it down to the minimum program that still exhibited this error. I am on Windows.

#include <windows.h>
#include <iostream>

HANDLE m_mutex;

void runFunction()
{
    ReleaseSemaphore(m_mutex, 1, NULL);
}

int main()
{
    std::cout << "Hello World!" << std::endl;

    m_mutex = CreateSemaphore(NULL, 1, 1, NULL);
    WaitForSingleObject(m_mutex, INFINITE);

    HANDLE m_handle = CreateThread(0, 5120, reinterpret_cast<LPTHREAD_START_ROUTINE>(runFunction), 0, 0, 0); 

    WaitForSingleObject(m_mutex, INFINITE);
    ReleaseSemaphore(m_mutex, 1, NULL);

    TerminateThread(m_handle, 0);
    CloseHandle(m_handle);

    CloseHandle(m_mutex);

    std::cout << "Done" << std::endl;

    return 0;
}

Ignore the poor coding style and the use of TerminateThread (I know that using that is bad), this is a case I am testing not one that I would implement. Still I would like to know why this freezes up the program, especially when something as simple as putting std::cout << "Test" << std::endl; in the middle makes the program no longer freeze. Also, "done" is printed, just the program never exits.

Upvotes: 1

Views: 323

Answers (1)

Werner Erasmus
Werner Erasmus

Reputation: 4076

The logic looks OK concerning the Semaphore. My apologies. I've not noticed the "1". I can only mention that you don't verify that the API functions actually complete successfully.

void runFunction()
{
    ReleaseSemaphore(m_mutex, 1, NULL);
}

int main()
{
    std::cout << "Hello World!" << std::endl;

    //OK - Count=1
    m_mutex = CreateSemaphore(NULL, 1, 1, NULL);
    WaitForSingleObject(m_mutex, INFINITE);

    //OK - Count=0

    HANDLE m_handle = CreateThread(0, 5120, reinterpret_cast<LPTHREAD_START_ROUTINE>(runFunction), 0, 0, 0); 

    //DO you know for sure that the thread has started??? The return value is never checked???

    //Now we not sure... Count may 1, or 0, because thread is not necessarily started immediately..

    //OK. We will block here. Count should no be 1 again, or should soon become it
    WaitForSingleObject(m_mutex, INFINITE);

    //Why???
    ReleaseSemaphore(m_mutex, 1, NULL);

    //Why so extreme? "Terminate thread is a dangerous function...." MSDN
    TerminateThread(m_handle, 0);
    CloseHandle(m_handle);

    CloseHandle(m_mutex);

    std::cout << "Done" << std::endl;

    return 0;
}

Upvotes: 1

Related Questions