簡體   English   中英

實現多線程UDP服務器的問題(線程池?)

[英]Problems implementing a multi-threaded UDP server (threadpool?)

我正在寫一個音頻流(客戶端 - 服務器)作為我的項目(C / C ++),我決定為這個項目制作一個多線程UDP服務器。

這背后的邏輯是每個客戶端將在他自己的線程中處理。 我遇到的問題是線程相互干擾。

我的服務器做的第一件事就是創建一種線程池; 它創建了5個線程,所有線程都被recvfrom()函數自動阻塞,雖然看起來,在我將多個線程連接到服務器的大多數時候,多個線程正在響應,之后導致服務器變為完全阻止而不是進一步操作。

調試這個也很困難所以我寫這里是為了獲得一些關於多線程UDP服務器通常實現的建議。

我應該在代碼的一部分中使用互斥鎖或信號量嗎? 如果是的話,在哪里?

任何想法都會非常有幫助。

退后一步:你說

每個客戶端都將在他自己的線程中處理

但UDP不是面向連接的。 如果所有客戶端使用相同的多播地址,則沒有自然的方法來決定哪個線程應該處理給定的數據包。


如果你堅持認為每個客戶端都有自己的線程(我通常會反對,但這里可能有意義),你需要一些方法來確定每個客戶端來自哪個客戶端。

這意味着

  • 使用TCP(因為你似乎正在嘗試面向連接的行為)
  • 讀取每個數據包,找出它所屬的邏輯客戶端連接,並將其發送到正確的線程。 請注意,由於路由信息是全局/共享狀態,因此這兩者是等效的:

    1. 保持源IP - >線程映射,受互斥鎖保護,讀取和訪問所有線程
    2. 在單個線程中執行所有讀取,使用本地源IP - >線程映射

    第一個似乎是你正在尋找的東西,但它的設計很糟糕。 當一個數據包進入時,你將喚醒一個線程,然后它鎖定互斥鎖並進行查找,並可能喚醒另一個線程。 您要處理此連接的線程也可能被阻止讀取,因此您需要一些機制來喚醒它。

    第二個至少給出了一個關注點(讀/分配與處理)。


明智地,您的設計應該依賴於

  • 客戶數量
  • I / O負載
  • 非I / O處理量(或IO:CPU比率,或......)

我的服務器做的第一件事就是創建一種線程池; 它創建了5個線程,所有線程都被recvfrom()函數自動阻塞,雖然看起來,在我將多個線程連接到服務器的大多數時候,多個線程正在響應,之后導致服務器變為完全阻止而不是進一步操作

您應該使用信號量保護連接,並讓工作線程等待信號量,而不是讓所有線程都位於同一套接字連接上的recvfrom()上。 當一個線程獲取信號量時,它可以調用recvfrom(),當它返回一個數據包時,線程可以釋放信號量(對於另一個要獲取的線程)並處理數據包本身。 當它完成對數據包的服務時,它可以返回等待信號量。 這樣您就可以避免在線程之間傳輸數據。

您的recvfrom應該在主線程中,當它獲取數據時,您應該將地址IP:UDP客戶端的端口和數據傳遞給幫助程序線程。

傳遞IP:端口和數據可以通過每次主線程接收UDP數據包時生成新線程來完成,或者可以通過消息隊列傳遞給輔助線程

我認為你的主要問題是非持久性udp連接。 Udp沒有保持你的連接存活,它每個會話只交換兩個數據報。 根據您的應用程序,在最壞的情況下,它將從第一個可用信息中讀取並發線程,即recvfrom()將取消阻止,即使輪到它也不會。

我認為可行的方法是在主線程中使用select,並使用並發緩沖區來管理線程將執行的操作。 在此解決方案中,每個客戶端可以有一個線程,或者每個文件有一個線程,假設您保留客戶端必要的信息以確保您發送正確的文件部分。

TCP是另一種方法,因為它為您運行的每個線程保持連接活動,但不是數據丟失允許的應用程序的最佳傳輸方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM