2015-06-13 72 views
0

我在阅读Qt的Blocking Fortune Client Example。有一段代码如下:为什么要在这里锁定QMutex?

mutex.lock(); 
    QString fortune; 
    in >> fortune; 
    emit newFortune(fortune); 

    cond.wait(&mutex); 
    serverName = hostName; 
    serverPort = port; 
    mutex.unlock(); 

我有点困惑,为什么它锁定第一行的互斥量。因为财富是局部变量。或散发应该保护?

这是代码:http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-fortunethread-cpp.html。整个项目可以在页面底部找到。

+0

我没有看到任何理由将锁定呼叫置于放置位置。我会在等待电话之前把它放好。但我没有深入研究完整的例子。不过,你本身并不需要保护发射。 – ixSci

+0

@ixSci:谢谢。这里是源代码,http://doc.qt.io/qt-5/qtnetwork-blockingfortuneclient-fortunethread-cpp.html,它很短。 – diverger

回答

1

似乎锁定在几乎正确的地方(我仍然把它放在in >> fortune;之后)。 为什么在排放之前可能需要lock

发送发生在一个线程中,而插槽在不同的线程中执行。因此,可能发生以下事件:

  1. T1发出信号并被操作系统暂停。
  2. T2获取时间定量和已经接收它开始执行所述槽(showFortune
  3. 如果nextFortune == currentFortune为真,那么线程的requestNewFortune在T2上下文被执行的信号。
  4. requestNewFortune试图锁定互斥但失败并被暂停。
  5. T1被恢复,并继续进行,直到cond.wait时它释放互斥,并得到悬浮
  6. 由于互斥被释放T2被恢复,并执行它的代码,其与cond.wakeOne
  7. T1结束得到由wakeOne呼叫恢复并完成它的代码正确。

如果我们在发出呼叫之前没有锁定互斥锁,该怎么办?我们最终可能会以类似

执行步骤4执行其代码与cond.wakeOne

结束了,这wakeOne将永远丢失,当T1会得到cond.wait它不会因为恢复致电等待的wakeOne已丢失。