2014-10-07 86 views
3

我在一次採訪中被問到了這一點,現在我很好奇,因爲我不認爲採訪者對我的回答滿意。這裏的問題:調試多線程服務器

多線程服務器應用程序停止工作,並從應用程序的最後一個日誌消息是:

"Some Server Related Message..." 

代碼如下所示:

CalledFunc() 
{ 
    Code ... 

    Acquiring Thread lock 
    Line printing "Some Server Related Message..." 
    Func(); 
    Releasing Thread Lock 
} 
  1. 什麼都要程序員負責做這個調試嗎?
  2. Func()發生了什麼問題?
  3. 如果在Func()中拋出異常,應該如何解決問題?
+0

是什麼樣的應用程序呢? – 2014-10-07 17:15:05

+1

你忘了問一個問題。你告訴我們一個很好的故事,大概你有一些問題,但你忘了實際問這個問題。像大多數面試問題一樣,沒有「一個正確的答案」。面試官希望聽到你如何推斷​​線程應用程序以及如何進行調試。另外,調試僞代碼非常困難。我們在談論什麼類型的鎖(遞歸?錯誤檢查?)以及我們如何獲得它(鎖定函數?RAII?)很重要。另外,爲什麼這個標籤C?這不是C++代碼還是我們在談論某種C異常方案?如果是這樣,什麼? – 2014-10-07 17:18:25

+0

@java_geek:我是新來的多線程和學習,因爲我們說話。訪員沒有具體說明這是什麼類型的應用程序,而只是爲了識別代碼和樣式的問題。 – joeroot 2014-10-08 09:01:51

回答

0

很可能是兩種:

  • Func鍵()正試圖再次獲得鎖(易查),或
  • Func鍵()已拋出以鎖定異常鎖定(更可能和微妙)

所以:

  1. 檢查函數功能的代碼T() Ø檢查所有可能的路徑(例外情況包括)解除鎖定
  2. 一兩個以上選項
  3. 釋放鎖引發異常之前,或趕在CalledFunc(除外),並釋放鎖
0

爲了克服Func()中的異常問題,您可以使用作用域鎖。 RAII是確保異常安全並避免一般泄漏的好方法。該鏈接也恰好以互斥爲例。

另外,在日誌中看到該行並不意味着問題來自於這部分代碼。

1

原因#1:這是一個數據庫問題。 這聽起來很奇怪,但應用程序服務器掛起的主要原因與應用程序服務器本身並沒有直接關係。症狀的位置很少是根本原因的位置。以下情況相當常見:

數據庫存在瓶頸,導致查詢運行速度比平時慢。 過去需要1秒鐘的請求,現在需要5秒鐘才能完成。 併發請求的平均數量緩慢增加(由於積壓)。 服務器用盡線程並且應用程序服務器掛起。 如果你設法得到一個線程轉儲,你會看到一堆線程正在等待,另一個線程正在運行。另一種可能性是等待線程(或排隊線程)的數量會吞噬所有可用內存,並最終導致OutOfMemory錯誤。

原因#2:死鎖。 如果看起來應用程序服務器無所事事,請查找死鎖。這些可能是導致您的SQL查詢掛起的數據庫死鎖,或者查找更新語句。例如,如果日誌表被鎖定,則寫入數據庫的每個請求的事務日誌可能會輕鬆掛起整個應用程序。同時檢查共享對象 - 一次寫入多個線程的操作系統文件。

原因#3:跑掉的線程。 如果應用程序服務器的確是有責任的話,你應該尋找一個失控的線程。這些很難被發現,因爲它們幾乎不會顯示在日誌中,因爲它們通常只在請求完成時才寫入。一個失控線程可能不會返回,直到它已經影響到整個應用程序。因此,掛起請求不會寫入日誌。這些「失控」線程通常包含無限循環或代碼,導致消耗太多的堆內存導致內存不足。例如,應顯示不包含結果頁面之間分頁選項的結果的查詢突然需要顯示大量結果。該頁面需要永久渲染和破壞應用程序服務器,最終導致它掛起。

+0

我假設你正在處理一個Web應用程序。有關應用程序本質的更多細節將有所幫助 – 2014-10-07 17:17:37

+0

因爲這顯然是C++,所以我會提及使用RAII來鎖定/互斥/事件等。 – paulm 2014-10-07 17:21:39

0

我認爲他們在哪裏尋找這樣的:

我應該負責的程序員做調試呢?

獲取進程的掛載轉儲,然後使用windbg找出原因,即如果它的死鎖,那麼它將顯而易見從轉儲。

Func()中發生了什麼問題?

從下一個問題我們可以認爲它必須拋出一個異常作爲某個點,導致鎖永遠不會被釋放,或者它試圖再次獲取鎖導致死鎖。

如果在Func()中拋出異常應該怎麼辦才能修復 的問題?

使用RAII是異常安全和更好/更乾淨的代碼。

+0

您似乎認爲這是一個特定於Windows的問題,即使它標記爲「pthreads 」。 – 2014-10-07 18:19:05

+0

可能是因爲pthreads是跨平臺的,爲Linux調試器切換「windbg」;) – paulm 2014-10-07 18:35:40