Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;上下文切换和互斥问题_C++_Mutex_Context Switch - Fatal编程技术网

C++ C++;上下文切换和互斥问题

C++ C++;上下文切换和互斥问题,c++,mutex,context-switch,C++,Mutex,Context Switch,好的。。以下是关于这个问题的一些背景。我有一些“关键”代码,我正试图用互斥来保护它们。事情是这样的 互斥锁 //关键代码 //一些文件IO Mutex.Unlock() 现在的问题是,我的程序似乎被“卡住”了。让我举例说明 线程_1进入;然后转到Mutex.Lock()并开始执行关键代码。在关键代码中;它需要执行一些文件IO。现在在这一点上;我相信会发生“上下文切换”,线程_2进入并阻塞Mutex.Lock()(因为线程_1拥有锁)。一切似乎都很好,但就我而言;程序“挂起”在这里。。我能想到的唯

好的。。以下是关于这个问题的一些背景。我有一些“关键”代码,我正试图用互斥来保护它们。事情是这样的

互斥锁

//关键代码 //一些文件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需要的任何内容


编辑:交换线程名称以更紧密地匹配问题中的场景,添加了“在互斥锁中”

针对类似情况的最佳解决方案是使用调试器()。最好使用带有调试器()的任何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()?从管道/插座?