如何让Ruby中的线程将字符串发送回父线程
我希望能够调用一个方法,该方法在一个单独的线程上重复x次,该线程每隔几分钟向控制台发送消息,例如“仍在运行”,而我可以自由调用执行相同操作的其他方法 这在我的测试环境中起作用,所有内容都通过rspec进行检查-但当我将代码移动到gem中并从另一个脚本调用它时,代码似乎在其他线程中工作,但字符串从未发送到我的控制台(或任何我能说的地方) 我将把代码的重要部分放在下面,但为了更好地理解,重要的是要知道:如何让Ruby中的线程将字符串发送回父线程,ruby,multithreading,Ruby,Multithreading,我希望能够调用一个方法,该方法在一个单独的线程上重复x次,该线程每隔几分钟向控制台发送消息,例如“仍在运行”,而我可以自由调用执行相同操作的其他方法 这在我的测试环境中起作用,所有内容都通过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
以下是所有通过的测试:
这里有一个非常简单的脚本(据我所知)应该打印“{Time.now}AAPL尚未达到800.54的目标。”该方法每1秒仍在运行,并且至少在20秒内可见(我使用rspec中的sleep进行测试,并且能够看到打印到控制台上的字符串):
然而,我没有得到任何输出——尽管程序需要等待20秒才能完成。如果我添加其他行打印到控制台,它们就可以正常工作,但是由TradeWatcher方法调用触发的线程中没有任何行可以正常工作
简言之,我不明白如何让线程彼此适当地通信,或者如何使它们彼此同步(我认为thread.join在这里不合适,因为它会使主线程挂起,并且如果我选择以后一次发送一个方法调用,则无法接受另一个方法调用)我对Ruby多线程的理解很弱,有人能理解我在这里想要得到什么,并将我推向正确的方向吗?当你开始打印时,看起来Ruby还没有加载pp函数。加入:
require 'pp'
在trade_watcher.rb的顶部,我能够获得您期望的输出。您可能还需要考虑添加:
$stdout.sync = $stderr.sync = true
您的二进制/可执行脚本,这样您的输出就不会被IO类内部缓冲,而是直接传递到操作系统。我将此移到堆栈溢出,因为代码复查不是询问“我该怎么做”问题的正确位置。
require 'pp'
$stdout.sync = $stderr.sync = true