C++ C++;上下文切换和互斥问题
好的。。以下是关于这个问题的一些背景。我有一些“关键”代码,我正试图用互斥来保护它们。事情是这样的 互斥锁 //关键代码 //一些文件IO Mutex.Unlock() 现在的问题是,我的程序似乎被“卡住”了。让我举例说明 线程_1进入;然后转到Mutex.Lock()并开始执行关键代码。在关键代码中;它需要执行一些文件IO。现在在这一点上;我相信会发生“上下文切换”,线程_2进入并阻塞Mutex.Lock()(因为线程_1拥有锁)。一切似乎都很好,但就我而言;程序“挂起”在这里。。我能想到的唯一一件事是,不知何故,线程2一直在阻塞,并且没有切换回线程1 更多信息:在linux上使用pthread_mutex_init和pthread_mutex_lock。这听起来像是线程1在mutext中等待线程2释放某些内容,而线程2等待进入互斥对象,因此无法释放线程1需要的任何内容C++ C++;上下文切换和互斥问题,c++,mutex,context-switch,C++,Mutex,Context Switch,好的。。以下是关于这个问题的一些背景。我有一些“关键”代码,我正试图用互斥来保护它们。事情是这样的 互斥锁 //关键代码 //一些文件IO Mutex.Unlock() 现在的问题是,我的程序似乎被“卡住”了。让我举例说明 线程_1进入;然后转到Mutex.Lock()并开始执行关键代码。在关键代码中;它需要执行一些文件IO。现在在这一点上;我相信会发生“上下文切换”,线程_2进入并阻塞Mutex.Lock()(因为线程_1拥有锁)。一切似乎都很好,但就我而言;程序“挂起”在这里。。我能想到的唯
编辑:交换线程名称以更紧密地匹配问题中的场景,添加了“在互斥锁中”针对类似情况的最佳解决方案是使用调试器()。最好使用带有调试器()的任何IDE,以使调试更容易、更直观 这样,您将看到每个线程正在等待的位置 我所期望的是,Thread1将互斥锁锁定以进入关键部分,线程卡在IO中(可能是错误读取或无限循环),线程2通常等待互斥锁解锁
这似乎不是一个死锁,因为死锁不能发生在一个互斥锁上 只要只有一个锁,上下文切换就无关紧要。另一个线程不能做任何事情来影响第一个线程,因为它只能等待锁,直到它得到它为止。所以问题出在第一个线程上。调试器对于多线程处理来说几乎一文不值,但死锁通常很容易解决,正如有人指出的,第一个线程可能不知何故处于无限循环中 正如其他人所提到的,您可能遇到了僵局 旁注: 您需要确保关键代码块中没有抛出任何未捕获的异常。否则锁将永远无法释放。您可以使用锁来解决此问题:
class SingleLock {
public:
SingleLock(Mutex &m) : m(m) { m.Lock(); }
~SingleLock() { m.Unlock(); }
private:
Mutex m;
};
...
{
SingleLock lock(mutex);
// critical code // some file IO
}
...
文件I/O是否需要是关键部分的一部分?如果线程1正在执行阻塞读取,而线程2应该写入该文件(或管道或类似文件),那么线程1将永远不会返回来释放互斥锁。您应该评估关键部分,以确定互斥锁实际需要保护的内容。让关键部分尽可能小被认为是一种好的做法。您使用的是哪个锁定/互斥库?您需要提供更多的信息。线程2是否准备输入线程1所在的代码块?是否涉及任何其他锁(它们可能是隐式的)?这是什么操作系统/线程实现?假设您使用的是标准线程库,这听起来不太可能。我更可能建议线程2正在休眠(在锁中),线程1正在等待线程2锁定的其他资源。在这里实际存在任何有效信息之前,您需要提供更多信息。此关键部分中的代码是否正在执行阻塞读取?如果读取永远不会返回,则互斥锁永远不会释放。如果是这样的话,问题实际上与互斥锁无关,互斥锁正在做它应该做的事情。它听起来确实像死锁。马丁:我愿意接受建议;线程_1已通过“Mutex.Lock()”并将执行一些文件IO。此时线程_2进入并“挂起”Mutex.Lock()?从管道/插座?