2014-09-13 100 views
-1

我正在運行一個線程將'數據'放到屏幕上。 線程的要點是阻止這個函數的阻塞,這樣我就可以在數據返回的時候向套接字發送數據。紅寶石線程仍然阻塞

def msg_loop() 
    t1 = Thread.new{ 
      loop do 
      msg = @socket.recv(30) 
      self.msg_dis(msg) 
      end 
     } 
     t1.join 
end 

但是,如果我跑

myclass.msg_loop 
myclass.send_msg("message to send") 

功能send_msg永遠不會運行,沒有比當msg_loop沒有線程不同。

+0

也許你想要一個Actor模型?有關信息,請參閱http://rubini.us/doc/en/systems/concurrency/或http://celluloid.io/。 – 2014-09-13 15:54:43

回答

2

t1.join導致程序等待線程t1完成運行。你想這樣做。

def msg_loop() 
    t1 = Thread.new{ 
     loop do 
     msg = @socket.recv(30) 
     self.msg_dis(msg) 
     end 
    } 
    t1 
end 

t1 = myclass.msg_loop 
myclass.send_msg("message to send") 
t1.join 
+0

該函數在類中定義,因此我無法在類之外調用t1.join。我可以發送我的消息,然後收到,但我不能發送任何其他內容。當我發送數據時,我需要持續打印到屏幕上。 – Corrosive 2014-09-13 08:33:16

+0

在這種情況下,如果我不運行t1.join,那麼您可能想要嘗試省略't1.join' – Reck 2014-09-13 08:52:18

+0

,然後我可以發送,但我仍然無法看到以我的方式返回的內容。所以我仍然有同樣的問題。 – Corrosive 2014-09-13 08:53:30

-2

Ruby不提供真正的線程(jruby呢)。 隨着一個無限循環,比如在紅寶石中使用線程,不會做任何事情,因爲循環永遠不會結束。

這使得線程永遠不會發生,從而阻塞發生。

+0

* Ruby不提供真正的線程(jruby)*不正確。由於Ruby 1.9(YARV,C Ruby)支持本地操作系統線程。這不是原因。這是因爲立即調用了'Thread#join',這與綠色/原生線程主題無關。 – 2014-09-13 12:31:55

+1

Ruby線程是複雜的野獸。 GIL的編寫方式是,以一個C函數的形式實現的Ruby操作不會對任何Ruby方法進行回調,它總是以原子方式執行。循環構造不滿足這個條件。任何不滿足此條件的操作都可以停止,另一個線程上的另一個操作可以更改爲運行。這意味着儘管你不能有真正的並行線程(即使你有多個處理器),但實際上你可以有多個線程在片中執行它們的操作。 – Reck 2014-09-13 18:57:50