2011-09-25 108 views
1

我正在設計一個客戶端和服務器套接字程序。 我有一個文件從客戶端使用UDP傳輸到服務器,我重複使用UDP ..... 我通過UDP發送所以,發送速度太快,然後接收器,所以我創建3個線程在同一套接字上偵聽,因此當一個線程正在接收數據時正在做一些工作(我的意思是使用fwrite寫入一個文件),另一個線程可以從客戶端接收數據。多線程與鎖vs單線程?

我的第一個問題是當我使用多線程的fwrite我必須使用鎖作爲文件指針在線程之間共享。我正確地認爲?

我的第二個問題是「如果我使用多個線程來使用鎖來使用單個線程執行fwrite工作而不使用鎖定,那麼性能會有任何改進...... ???」指導我...

回答

1

類似Ed's answer,我建議使用異步I/O,併爲您的服務器的單個線程。儘管我發現使用Boost.Asio比posix AIO更容易。

2

在寫入數據之前緩存數據。 讓寫作發生在另一個線程中。

這樣做的方式需要鎖定套接字。第一季度:是的,你需要鎖定它(非常慢!)。爲什麼不在每個線程中使用單獨的文件描述符?問題主要與當前文件位置由該描述符管理。 Q2:也沒有。如果數據需要排序(是的,UDP!),你仍應該緩衝它。 RAM比磁盤IO快得多。提供一個流來緩衝它,並在一個單獨的線程中處理該流中的數據。

+0

我不認爲我阻止了套接字....因爲我在接收後做了fwrite,並且一旦我從套接字中獲得了數據,就離開套接字......所以,您怎麼看我阻止了套接字? – Invictus

+0

數據收到的順序不重要嗎?如果它不知道該如何寫入該文件?給我更多關於實際需求的信息可能會有所幫助,但是我仍然建議緩存 - 如果沒有其他的話,它可以更好地控制並行性。 – long404

1

我的第一個問題是,當我使用多線程我有作爲文件指針的線程之間共享使用鎖一FWRITE

是的,你總是有當多個線程使用鎖正在寫入一個單一的對象(文件,內存等)。

我的第二個問題是:「是否會有,如果我使用多線程使用鎖在使用單線程做fwrite的工作,沒有鎖使用fwrite性能的任何改善... ???」

我會使用兩個線程。第一個線程什麼都不做,只是從套接字中讀取並將數據存儲在內存中。第二個線程從內存中讀取數據並將其寫入文件。將內存緩衝區視爲FIFO隊列,並使用互斥鎖來保護隊列指針。你會從第三個線程中獲得任何東西。事實上,這可能會損害性能,這絕對會讓問題變得更加複雜。

1

首先,儘量避免使用UDP進行批量傳輸。如果您使用UDP,則必須重新創建自己的流量控制協議,以及重新傳輸和重新排序的邏輯。從它的聲音,你的問題歸結爲缺少流量控制 - 爲什麼不使用TCP?

無論如何,不​​要把你的文件寫在另一個線程中。現代操作系統在任何情況下都會在內部緩衝磁盤寫入 - 如果您的數據寫入速度比磁盤更快,那麼您只會開始阻止,在這種情況下,緩衝內部流程最多隻會花費您幾秒鐘的時間。切換到TCP,或實施適當的流量控制機制。