我想能够调用一个方法,在一个单独的线程上重复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