我想能夠調用一個方法,在一個單獨的線程上重複x次的時間,每隔幾個時間發送消息如「仍在運行」到控制檯,而我可以自由地調用其他方法來做同樣的事情。你如何在Ruby中的線程發送字符串回到父線程
這在我的測試環境中工作,一切都通過rspec檢查 - 但是當我將代碼移動到gem並從另一個腳本調用它時,看起來該代碼在其他線程中工作,但字符串不會發送到我的控制檯(或者我可以告訴的任何地方)。
我會把下面的代碼的重要組成部分,但爲了更好地理解它知道這是很重要的:
- 代碼將查詢股票的市場價格在設定的時間間隔與通知用戶的意圖當所述股票的價值達到特定價格時。
- 代碼應該向控制檯顯示一條消息,指出代碼在價格尚未達到時仍在運行。
- 該代碼應告訴用戶該股票已達到目標價格,然後停止循環。
下面是代碼:
require "trade_watcher/version"
require "market_beat"
module TradeWatcher
def self.check_stock_every_x_seconds_for_value(symbol, seconds, value)
t1 = Thread.new{(self.checker(symbol, seconds, value))}
end
private
def self.checker(symbol, seconds, value)
stop_time = get_stop_time
pp stop_time
until is_stock_at_or_above_value(symbol, value) || Time.now >= stop_time
pp "#{Time.now} #{symbol} has not yet met your target of #{value}."
sleep(seconds)
end
if Time.now >= stop_time
out_of_time(symbol, value)
else
reached_target(symbol, value)
end
end
def self.get_stop_time
Time.now + 3600 # an hour from Time.now
end
def self.reached_target(symbol, value)
pp "#{Time.now} #{symbol} has met or exceeded your target of #{value}."
end
def self.out_of_time(symbol, value)
pp "#{Time.now} The monitoring of #{symbol} with a target of #{value} has expired due to the time limit of 1 hour being rached."
end
def self.last_trade(symbol)
MarketBeat.last_trade_real_time symbol
end
def self.is_stock_at_or_above_value(symbol, value)
last_trade(symbol).to_f >= value
end
end
下面是測試(所有通):
require 'spec_helper'
describe "TradeWatcher" do
context "when comparing quotes to targets values" do
it "can report true if a quote is above a target value" do
TradeWatcher.stub!(:last_trade).and_return(901)
TradeWatcher.is_stock_at_or_above_value(:AAPL, 900).should == true
end
it "can report false if a quote is below a target value" do
TradeWatcher.stub!(:last_trade).and_return(901)
TradeWatcher.is_stock_at_or_above_value(:AAPL, 1000).should == false
end
end
it "checks stock value multiple times while stock is not at or above the target value" do
TradeWatcher.stub!(:last_trade).and_return(200)
TradeWatcher.should_receive(:is_stock_at_or_above_value).at_least(2).times
TradeWatcher.check_stock_every_x_seconds_for_value(:AAPL, 1, 400.01)
sleep(2)
end
it "triggers target_value_reahed when the stock has met or surpassed the target value" do
TradeWatcher.stub!(:last_trade).and_return(200)
TradeWatcher.should_receive(:reached_target).exactly(1).times
TradeWatcher.check_stock_every_x_seconds_for_value(:AAPL, 1, 100.01)
sleep(2)
end
it "returns a 'time limit reached' message once a stock has been monitored for the maximum of 1 hour" do
TradeWatcher.stub!(:last_trade).and_return(200)
TradeWatcher.stub!(:get_stop_time).and_return(Time.now - 3700)
TradeWatcher.check_stock_every_x_seconds_for_value(:AAPL, 1, 100.01)
TradeWatcher.should_receive(:out_of_time).exactly(1).times
sleep(2)
end
end
這裏是一個非常簡單的腳本,(在我的理解)應打印「{Time.now} AAPL尚未達到800.54的目標。」每1秒,該方法仍在運行,應該至少是20秒可見的(我測試這個使用睡眠RSpec的和我能看到打印到控制檯的字符串):
require 'trade_watcher'
TradeWatcher.check_stock_every_x_seconds_for_value(:AAPL, 1, 800.54)
sleep (20)
但是我沒有得到任何輸出 - 儘管該程序等待20秒完成。如果我添加其他行來打印到控制檯,他們工作得很好,但我的TradeWatcher方法調用觸發的線程中沒有任何內容實際工作。
總之,我不理解如何讓線程相互適當地溝通 - 或者如何將它們彼此同步(我不認爲thread.join在這裏是合適的,因爲它會離開主線程如果我選擇在將來一次發送一個,則無法接受另一個方法調用)。 我對Ruby多線程的理解很弱,任何人都能理解我想要在這裏得到什麼,並將我推向正確的方向?
我已經把這個移動到堆棧溢出,因爲Code Review不是問「我該怎麼」問題的正確位置。 – sepp2k 2013-04-21 09:54:54