[英]Problems implementing a multi-threaded UDP server (threadpool?)
我正在寫一個音頻流(客戶端 - 服務器)作為我的項目(C / C ++),我決定為這個項目制作一個多線程UDP服務器。
這背后的邏輯是每個客戶端將在他自己的線程中處理。 我遇到的問題是線程相互干擾。
我的服務器做的第一件事就是創建一種線程池; 它創建了5個線程,所有線程都被recvfrom()
函數自動阻塞,雖然看起來,在我將多個線程連接到服務器的大多數時候,多個線程正在響應,之后導致服務器變為完全阻止而不是進一步操作。
調試這個也很困難所以我寫這里是為了獲得一些關於多線程UDP服務器通常實現的建議。
我應該在代碼的一部分中使用互斥鎖或信號量嗎? 如果是的話,在哪里?
任何想法都會非常有幫助。
退后一步:你說
每個客戶端都將在他自己的線程中處理
但UDP不是面向連接的。 如果所有客戶端使用相同的多播地址,則沒有自然的方法來決定哪個線程應該處理給定的數據包。
如果你堅持認為每個客戶端都有自己的線程(我通常會反對,但這里可能有意義),你需要一些方法來確定每個客戶端來自哪個客戶端。
這意味着
讀取每個數據包,找出它所屬的邏輯客戶端連接,並將其發送到正確的線程。 請注意,由於路由信息是全局/共享狀態,因此這兩者是等效的:
第一個似乎是你正在尋找的東西,但它的設計很糟糕。 當一個數據包進入時,你將喚醒一個線程,然后它鎖定互斥鎖並進行查找,並可能喚醒另一個線程。 您要處理此連接的線程也可能被阻止讀取,因此您需要一些機制來喚醒它。
第二個至少給出了一個關注點(讀/分配與處理)。
明智地,您的設計應該依賴於
我的服務器做的第一件事就是創建一種線程池; 它創建了5個線程,所有線程都被recvfrom()函數自動阻塞,雖然看起來,在我將多個線程連接到服務器的大多數時候,多個線程正在響應,之后導致服務器變為完全阻止而不是進一步操作
您應該使用信號量保護連接,並讓工作線程等待信號量,而不是讓所有線程都位於同一套接字連接上的recvfrom()上。 當一個線程獲取信號量時,它可以調用recvfrom(),當它返回一個數據包時,線程可以釋放信號量(對於另一個要獲取的線程)並處理數據包本身。 當它完成對數據包的服務時,它可以返回等待信號量。 這樣您就可以避免在線程之間傳輸數據。
您的recvfrom應該在主線程中,當它獲取數據時,您應該將地址IP:UDP客戶端的端口和數據傳遞給幫助程序線程。
傳遞IP:端口和數據可以通過每次主線程接收UDP數據包時生成新線程來完成,或者可以通過消息隊列傳遞給輔助線程
我認為你的主要問題是非持久性udp連接。 Udp沒有保持你的連接存活,它每個會話只交換兩個數據報。 根據您的應用程序,在最壞的情況下,它將從第一個可用信息中讀取並發線程,即recvfrom()將取消阻止,即使輪到它也不會。
我認為可行的方法是在主線程中使用select,並使用並發緩沖區來管理線程將執行的操作。 在此解決方案中,每個客戶端可以有一個線程,或者每個文件有一個線程,假設您保留客戶端必要的信息以確保您發送正確的文件部分。
TCP是另一種方法,因為它為您運行的每個線程保持連接活動,但不是數據丟失允許的應用程序的最佳傳輸方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.