【问题标题】:If a thread locks a mutex and doesn't unlock it, shouldn't be the rest of threads blocked?如果一个线程锁定了一个互斥体并且没有解锁它,那么其余的线程不应该被阻塞吗?
【发布时间】:2019-08-20 01:27:10
【问题描述】:

下面代码的输出是4000; 如果具有互斥锁的线程没有释放它,为什么它是 4000。我虽然这将是一个死锁,但我主要等待所有功能完成。

int M = 1000;
HANDLE mutex;
DWORD WINAPI thread_function(LPVOID param) // The thread function
{
    long aux;
    WaitForSingleObject(mutex, INFINITE);
    for (int i = 0; i < M; i++)
    {
        aux = count;         //count is global
        aux++;
        Sleep(0.5);
        count = aux;
    }
    /*ReleaseMutex(mutex);*/
    return (DWORD)0;
}
int main()
{
    int N = 4;
    InitializeCriticalSection(&gSection);
    HANDLE* iThread = (HANDLE*)malloc(N * sizeof(HANDLE));
    mutex = CreateMutex(NULL, FALSE, NULL);
    for (int i = 0; i < N; i++)    // N = 4, i create 4 threads
    {
        iThread[i] = CreateThread(NULL, 0, thread_function, mutex, 0, NULL);
    }
    WaitForMultipleObjects(4, iThread, TRUE, INFINITE); // I wait for all threads to finish.
    printf("%d", count);
}

预期结果为死锁,实际结果为 4000(count = 4000)。

【问题讨论】:

  • 无错误检查。酌情查看返回码和 GetLastError(),您可能会自己找出答案。
  • 互斥锁强制所有4个线程依次执行。当第一个获得它的线程完成并消失时,它就失去了所有权。这意味着这段代码不仅等待线程停止工作,它还等待线程被删除。所以这段代码比单线程程序效率低得多。
  • 为了将来参考,请用winapi标记有关Windows线程的问题。这会引起正确的人对问题的关注。

标签: c multithreading winapi mutex


【解决方案1】:

其他线程被阻塞,直到持有互斥锁的线程结束。在线程的(正常)结束时,互斥锁会自动释放,因为没有人持有它。但是使用该功能是不好的编码习惯。您应该始终显式释放互斥锁。

【讨论】:

  • "互斥锁自动释放" - 不只是释放,而是放弃。随后对互斥体的等待操作将报告WAIT_ABANDONED:“指定的对象是一个互斥体对象,在拥有该互斥体对象的线程终止之前,拥有该互斥体对象的线程没有释放。所有权互斥对象的一部分被授予调用线程,并且互斥状态设置为非信号”。许多程序员没有正确处理WAIT_ABANDONED。见Understanding the consequences of WAIT_ABANDONED
  • @Remy Lebeau 这个案例不是共享内存示例,而是多线程示例,线程之间共享内存。因此,在这种情况下,您通常不必正确处理它,因为您需要做一些有趣的事情,例如显式终止线程以达到 WATI_ABANDONED 状态并不意味着线程正常退出并且不执行程序你的整个程序。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2023-03-24
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多