2013-04-11 97 views
0

所以我的代碼工作正常,除了迭代通過數組並向多個聊天客戶端發送響應時,每個客戶端接收響應之間的延遲幾乎是一秒鐘。我在我的電腦上運行服務器和客戶端,所以不應該有任何實際的延遲,對不對?我知道紅寶石不是這麼慢。另外,爲什麼我的電腦風扇在運行時會旋轉起來?如果包含它會有幫助。使用套接字和線程爲什麼我的聊天服務器速度如此之慢以及CPU使用率如此之高?

# Creates a thread per client that listens for any messages and relays them to the server viewer and all the other clients. 
create_client_listener_threads = Thread.new do 
    x = nil 
    client_quantity = 0 
    # Loops indefinitely 
    until x != nil 
     #Checks to see if clients have joined since last check. 
     if @client_join_order_array.size > client_quantity 
      # Derives number of new arrivals. 
      number_of_new_arrivals = @client_join_order_array.size - client_quantity 
      # Updates number of clients in client_quantity. 
      client_quantity = @client_join_order_array.size 
      if number_of_new_arrivals != 0 
       # Passes new arrivals into client for their thread creation. 
       @client_join_order_array[-1 * number_of_new_arrivals..-1].each do |client| 
        # Creates thread to handle receiving of each client's text. 
        client_thread = Thread.new do 
         loop do 
          text = client.acception.gets 
          # Displays text for server viewer. 
          puts "#{client.handle} @ #{Time.now} said: #{text}" 
          @client_hash.each_value do |value| 
           if value.handle != client.handle 
            # Displays text for everyone except server viewr and person who spoke. 
            value.acception.puts "#{client.handle} @ #{Time.now} said: #{text}" 
           end 
          end 
         end 
        end 
       end 
      end 
     end 
    end 
end 
+1

它看起來像你的循環沒有等待旋轉。這將使CPU熱... – usr 2013-04-11 11:34:37

+0

是的。向主線添加睡眠(1)可以解決我所有的問題。我仍然感到困惑,因爲我有其他線程在不停地旋轉,而不是每次運行時將數字與另一個數字進行比較,但它們不會導致CPU使用率過高或延遲。 – cyclingLinguist 2013-04-11 18:04:59

+0

好的。我現在明白了。它看起來像我的其他線程做更多,但他們實際上都等待來自客戶端或來自服務器用戶的輸入。我認爲他們造成了所謂的全球口譯員鎖。我認爲,在等待投入時(至少從客戶那裏),他們必須反覆做一些事情。但這顯然不是真的。 – cyclingLinguist 2013-04-11 18:16:59

回答

1

相反測試if @client_join_order_array.size > client_quantity,無所事事,除了抽菸,如果是假的CPU,你應該接受在這一點上新的連接和阻塞,直到有一個。換句話說,移動接受連接的代碼並將它們添加到數組中。

+0

感謝您的建議。添加sleep()確實阻止了CPU吸菸,但是您的想法鞏固了我的代碼,並讓我意識到我不需要單獨的線程來連接客戶端並添加線程來讀取和重新分發他們的消息。謝謝! – cyclingLinguist 2013-04-17 03:55:05

+0

您不需要任何東西,更不用說一個線程,用於連接到客戶端。客戶連接到你。您只需要一個接受循環,併爲每個客戶端處理其I/O的線程。 – EJP 2013-04-17 09:14:47

相關問題