2015-06-13 91 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已丟失。