2012-12-10 60 views
4

我是新来的助推库,它是如此惊人的库!另外,我对互斥体很陌生,所以如果我犯了一个新手错误,请原谅我。提升互斥锁定在同一线程上

无论如何,我有两个函数叫做FunctionOneFunctionTwoFunctionOneFunctionTwo由不同的线程异步调用。所以发生了什么:在FunctionOne中,我在函数的开头锁定了全局互斥锁,并在函数结束时解锁了全局互斥锁。 FunctionTwo同样的事情。

现在问题出现了:有时,FunctionOneFunctionTwo被称为间隔少于几毫秒(并非总是如此)。所以,FunctionOne开始执行,并通过FunctionTwo中途执行。当FunctionTwo锁定互斥锁时,FunctionOneFunctionTwo所在的整个线程停止,所以FunctionOne中途卡住,线程永远等于FunctionTwo本身。因此,总结一下:

  • 函数1锁定互斥锁并开始执行代码。
  • 函数2在几秒后被调用并锁定互斥锁,冻结线程func 1和2。
  • 现在func 1卡住了一半,线程被冻结,所以func 1永远不会结束,互斥锁永远被锁定,等待func 1完成。

在这种情况下,人们会做什么?这里是我的代码:

boost::mutex g_Mutex; 
lua_State* L; 

// Function 1 is called from some other thread 
void FunctionOne() 
{ 
    g_Mutex.lock(); 

    lua_performcalc(L); 

    g_Mutex.unlock(); 
} 

// Function 2 is called from some other thread a few ms later, freezing the thread 
// and Function 1 never finishes 
void FunctionTwo() 
{ 
    g_Mutex.lock(); 

    lua_performothercalc(L); 

    g_Mutex.unlock(); 
} 
+2

如果f1和f2由同一个线程调用,那么如何F2可以称得上而F1仍在进行中?你的意思是从f1调用f2吗? –

+0

这就是我所困惑的。我确信FunctionOne和FunctionTwo是从一个单独的线程调用的。但是,我做了以下操作:'printf(“Function:%s,time:%f”,__FUNCTION__,globals-> currentTime());'有时候这两个函数都会立即调用(并且应用程序崩溃以便写入相同的资源),并通过一个互斥体,应用程序在自己的线程上等待。 – arao6

+0

-1这个问题需要一个SSCCE。见http://www.sscce.org/正如你在浪费你自己的时间,也是为了我们的。 **更新**嗯。为什么RSS提要中的旧问题? – sehe

回答

8

难道这些功能打算重入,这样FunctionOne会调用自身或FunctionTwo同时持有互斥?反之亦然,FunctionTwo锁定互斥锁,然后在锁定互斥锁的同时调用FunctionOne/FunctionTwo?

  • 如果不是,那么你不应该从同一个线程调用这两个函数。如果你打算FunctionTwo阻塞,直到FunctionOne完成,那么在同一个线程中调用它是一个错误。如果lua_performcalc最终调用FunctionTwo,就会发生这种情况。这将是他们可以在同一个线程上调用的唯一方法。

  • 如果是这样,那么你需要一个recursive_mutex。常规互斥锁只能锁定一次;从同一个线程再次锁定它是一个错误。递归互斥锁可以被单个线程多次锁定,并被锁定,直到线程调用解锁相同的次数。

无论哪种情况,都应该避免显式调用锁定和解锁。如果抛出异常,互斥锁将无法解锁。最好使用RAII式锁定,如下所示:

{ 
    boost::recursive_mutex::scoped_lock lock(mutex); 

    ...critical section code... 

    // mutex is unlocked when 'lock' goes out of scope 
} 
+0

即使需要重新调用,你也可以避免递归互斥。 – 2012-12-10 17:59:56

+0

这两个函数保证永远不会互相调用或它自己,但是这两个函数使用相同的资源和子例程(例如lua_getglobal,lua_gettop等)。当我记录FunctionOne和FunctionTwo运行的时间时,它们被不同的线程同时调用(到小数点后8位),线程永远挂起。有时这些函数相隔几毫秒,然后就没有问题了(通常情况下,除非时间差很小)。我不认为两个函数可以在同一个线程上同时执行,所以我不知道为什么会发生这种情况。 – arao6

3

你的描述是不正确的。一个互斥锁不能被锁定两次。你有一个不同的问题。

  • 锁定互斥锁时检查再入口。
  • 检查异常

,以避免与异常的问题,你应该使用boost::mutex::scoped_lockRAAI

+0

使用scoped_lock,等待的问题消失了,但现在这两个函数似乎一次写入同一资源。显然有一些我不理解。 :( – arao6

+0

如果scoped_lock确实解决了死锁,那么'lua_performcalc(L);'可能会引发 – stefan

+0

当我记录时间时,FunctionOne和FunctionTwo有时会同时触发(至小数点后8位),lua_performcalc和lua_performothercalc尝试写入相同的资源和崩溃,有时当它们相距几毫秒时,它们也会崩溃,只有当两个函数相距几百毫秒时,它们才会崩溃,当我使用'g_Mutex.lock() '相反,线程自身挂起,我认为两个函数不能同时在同一个线程上执行,所以我不知道为什么会发生这种情况。 – arao6