为什么在一个单独的线程中使用信号量会冻结程序?

时间:2015-07-29 18:48:44

标签: c++ windows multithreading

我遇到了这个问题,所以我把它归结为仍然出现此错误的最小程序。我在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;
}

忽略糟糕的编码风格和TerminateThread的使用(我知道使用它很糟糕),这是我测试的一个案例,而不是我要实现的。我仍然想知道为什么这会冻结程序,特别是当在中间放置std::cout << "Test" << std::endl;之类的简单程序使程序不再冻结时。此外,&#34;完成&#34;打印出来,只是程序永远不会退出。

1 个答案:

答案 0 :(得分:1)

关于信号量的逻辑看起来很好。我很抱歉。我没注意到“1”。我只能提到你没有验证API函数是否真正成功完成。

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;
}