简而言之,Ruby 中的标准库Logger类是线程安全的吗?谷歌出现的唯一有用信息是论坛上有人说它“似乎”是线程安全的。而且我不想花时间测试记录器来试图弄清楚它是否存在。
目前我使用的是线程安全的log4r,但如果标准库已经这样做了,那就太矫枉过正了。
快速浏览 logger.rb 会发现如下代码:
def write(message)
@mutex.synchronize do
if @shift_age and @dev.respond_to?(:stat)
begin
check_shift_log
rescue
raise Logger::ShiftingError.new("Shifting failed. #{$!}")
end
end
@dev.write(message)
end
end
因此,虽然我不能保证它是否获得了正确的线程安全,但我可以确认它正在齐心协力地做正确的事!
PS 通过阅读代码通常很容易为自己回答这样的问题 :-)
以下是我的原始回复,实际上是错误的。阅读下面 Nemo157 的评论。我把它留在这里仅供参考。
原来的:
我不认为这很重要。到目前为止,我所知道的所有 Ruby 实现都一次有效地运行一个线程:它确实允许您启动多个线程,但每个进程一次只能运行一个线程。
一些 Ruby 类被设计为线程安全的,但在他们的文档中并没有明确地用一个音节的话来说明这一点。与 PHP 等其他编程语言的文档不同。
我记得有人问我Queue
Stack Overflow 上是否是线程安全的,即使是这样,文档也没有说明这一点。
试试日志是否会在多线程中混合
require 'logger'
require 'parallel'
logger = Logger.new("/tmp/test.log")
Parallel.map(['a','b'], :in_threads => 2) do |letter|
1000.times do
logger.info letter * 5000
end
end
测试日志文件
egrep -e 'ab' -e 'ba' /tmp/test.log
[empty]
日志没有混合的原因:
def write(message)
@mutex.synchronize do
...
@dev.write(message)
end
end