31

简而言之,Ruby 中的标准库Logger类是线程安全的吗?谷歌出现的唯一有用信息是论坛上有人说它“似乎”是线程安全的。而且我不想花时间测试记录器来试图弄清楚它是否存在。

目前我使用的是线程安全的log4r,但如果标准库已经这样做了,那就太矫枉过正了。

4

4 回答 4

49

快速浏览 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 通过阅读代码通常很容易为自己回答这样的问题 :-)

于 2011-01-11T17:06:50.807 回答
0

以下是我的原始回复,实际上是错误的。阅读下面 Nemo157 的评论。我把它留在这里仅供参考。

原来的:

我不认为这很重要。到目前为止,我所知道的所有 Ruby 实现都一次有效地运行一个线程:它确实允许您启动多个线程,但每个进程一次只能运行一个线程。

于 2011-01-11T18:27:46.307 回答
0

一些 Ruby 类被设计为线程安全的,但在他们的文档中并没有明确地用一个音节的话来说明这一点。与 PHP 等其他编程语言的文档不同。

我记得有人问我QueueStack Overflow 上是否是线程安全的,即使是这样,文档也没有说明这一点。

于 2011-01-11T23:14:17.120 回答
0

来源

试试日志是否会在多线程中混合

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
于 2020-10-06T12:27:18.227 回答