2010-02-06 123 views
0

我有一個基本的Win32控制檯應用程序,它可以調用一個命名管道,然後在一個while(true)循環內調用Sleep(1000)。經過一百次迭代後,睡眠(1000)將掛起。我看不出有什麼理由。爲什麼睡眠(1000)導致死鎖?

好了,所有我做的是這個MSDN樣本中發現的代碼,逐字記錄和運行它的服務器:http://msdn.microsoft.com/en-us/library/aa365601%28VS.85%29.aspx

然後我藉此MSDN樣本客戶端發現這裏找到的代碼: http://msdn.microsoft.com/en-us/library/aa365592%28VS.85%29.aspx,我修改它,以便它使所有的調用代碼到一個單獨的方法,然後從內部main()調用它像這樣:

while (true) 
    { 
     sendmsg(); 
     Sleep(1000); 
    } 

我要補充一點,這個問題發生在我運行多個客戶端的實例,例如大約4或5個實例。我看不出有什麼理由。沒有任何同步發生。代碼與兩個鏈接中的代碼完全相同,除了在循環中運行客戶端代碼的更改以外,每次調用後都使用Sleep(1000)。

+0

發佈一些代碼。 – Joe 2010-02-06 02:54:25

回答

1

睡眠不能掛起。注意調試器的行爲,如果它沒有任何活動代碼的源代碼,它往往會在下一個語句中放置綠色箭頭。看到一個管道調用掛起將是非常正常的。在Debug + Break All之後,確保將堆棧跟蹤向上滾動到操作系統代碼中的幀。

+0

那麼,有沒有人看到爲什麼在我提供的由微軟提供的鏈接中的代碼在多個客戶端連接時會掛起的原因? – 2010-02-06 04:07:01

+2

我懷疑鏈接代碼掛起。你可能會這樣做,因爲你不再讀取服務器的響應。管道緩衝區將填滿容量,然後掛起等待緩衝區排空。 – 2010-02-06 04:38:37

+0

嗯,我運行完全相同的代碼,包括客戶端在發送消息後讀取管道的鏈接。實際上,我所改變的是,我將客戶端示例中的代碼移動到了一個名爲sendmsg()的單獨函數中,然後我只是在while循環中重複調用它,在每次調用後都會休眠。如果你已經理解了這一點,但仍然認爲我錯過了你的觀點,請告訴我,我只想清楚自己在做什麼。我可以發佈整個客戶端代碼,它與我鏈接的代碼幾乎完全相同。 – 2010-02-06 04:43:54

1

因此,當多個客戶端正在運行並在顯示的緊密循環中連接和發送時,一個(或多個?)客戶端會阻塞?

分解代碼,當它被阻塞併發布堆棧跟蹤時。

當所有管道實例都很忙時,您確定沒有在示例代碼中發生的20秒等待中阻塞?我不認爲這是可能的,但它可能...

這可能是最好的你發佈你正在使用的確切代碼。您可能在將代碼移入您所調用的函數的過程中犯了錯誤,並且可能會泄漏資源或導致您出現問題的某些內容。

由於您正在運行多個客戶端,因此從每個客戶端輸出一個循環計數器以顯示它們在進行問題前可以進行多少次迭代可能很有用;也許它總是迭代次數相同?你是否更快地與更多的客戶掛?用更少的客戶減少速度?