我試圖實現一個基於UDP的服務器,它維護兩個插座,一個用於控制(ctrl_sock
),另一個用於數據傳輸(data_sock
)。事情是,ctrl_sock
總是上行鏈路,data_sock
是下行鏈路。也就是說,客戶端將通過ctrl_sock
請求數據傳輸/停止,數據將通過data_sock
發送給他們。在兩個插座之間共享信息
現在的問題是,由於模型沒有連接,服務器將不得不維護已註冊客戶信息的列表(我稱之爲peers_context
),以便它可以「盲目地」向他們推送數據,直到他們詢問停止。在此盲傳期間,客戶端可能會異步通過ctrl_sock
向服務器發送控制消息。除了初始請求和停止之外,這些信息也可以是例如文件部分的偏好。因此,peers_context
必須異步更新。然而,通過data_sock
的傳輸依賴於這個peers_context
結構,因此引起了ctrl_sock
和data_sock
之間的同步問題。我的問題是,我能做些什麼來安全地維護這兩個襪子和peers_context
結構,這樣異步更新peers_context
不會造成嚴重破壞。順便說一下,peers_context
的更新不會很頻繁,這就是爲什麼我需要避免請求 - 回覆模型。
我最初考慮的實現是在主線程(listener線程)中維護ctrl_sock,並且在另一個線程(工作線程)中維護通過data_sock
進行的傳輸。但是,我發現在這種情況下很難同步。例如,如果我在peers_context
中使用互斥鎖,每當工作線程鎖定peers_context
時,由於工作線程無休止地工作,偵聽線程在它需要修改peers_context
時不再有權訪問它。另一方面,如果偵聽器線程持有peers_context
並寫入它,工作線程將無法讀取peers_context
並終止。有人可以給我一些建議嗎?
順便說一下,這個實現是在C語言的Linux環境下完成的。只有監聽線程偶爾需要修改peers_context
,工作線程只需要讀取。衷心感謝!
爲什麼不使用TCP?您可以與每個客戶端建立基於流的連接,並執行必要的通信,而不用擔心同步它。比UDP更容易,更可靠。 – Raam 2012-04-19 18:06:42
聽起來像你只需要稍微複雜的鎖定。顯然你不能讓工人無休止地鎖住。您需要鎖定,發送數據包,解鎖 – TJD 2012-04-19 18:10:04
使用select()或poll()將這個狀態機重新編碼爲狀態機是否可能/合意?這可能比一個線程化設計更好,並且避免了所有這些刺激的線程同步問題! – 2012-04-19 18:19:53