Ruby 确保线程安全

Ruby 确保线程安全,ruby,multithreading,Ruby,Multithreading,我有一个多线程程序,可以打印到数百个地方的控制台。不幸的是 Line 2 Line 1 Line 3 我明白了 我正在尝试使put线程安全 在Python中(我认为它没有这个问题,但假设它有),我会这样做 我用Ruby试试这个 old_puts = puts puts_mutex = Mutex.new def puts(*args) puts_mutex.synchronize { old_puts(*args) } 但这不起作用:“未定义的方法old

我有一个多线程程序,可以打印到数百个地方的控制台。不幸的是

Line 2
Line 1
Line 3
我明白了

我正在尝试使
put
线程安全


在Python中(我认为它没有这个问题,但假设它有),我会这样做

我用Ruby试试这个

old_puts = puts

puts_mutex = Mutex.new

def puts(*args)
    puts_mutex.synchronize {
        old_puts(*args)
    }
但这不起作用:“未定义的方法
old\u put


如何使线程安全(即不打印部分行)

或者更现代的方式:

module MyKernel
  PutsMutex = Mutex.new
  def puts(*)
    PutsMutex.synchronize{super}
  end
end

module Kernel
  prepend MyKernel
end

这种行为的原因是,
put
在内部调用底层的
write
函数两次,一次用于写入实际值,另一次用于写入换行符。(以英文解释)

下面是一个让
put
调用
write
只执行一次的技巧:将
\n
附加到正在编写的字符串中。以下是我的代码中的内容:

# Threadsafe `puts` that outputs text and newline atomically
def safe_puts(msg)
    puts msg + "\n"
end

put
内部检查正在写入的对象的末尾是否有换行符,如果不是这样,则仅再次调用
write
。由于我们已将输入更改为以换行结束,
put
只对
write

进行了一次调用提示:当您执行
old\u put=put
时,您是在隐式执行
old\u put=put()
这是否意味着如果您使用
print
而不是
put
,如果将换行符作为字符串的一部分传递给
print
,您就不需要
安全的puts
?而且,对我来说,我真正需要的是一种在一个原子操作中打印多行的方法。我想我需要像我之前建议的那样,自己构建多行字符串,然后将其传递给
print
?是,是:)
alias old_puts puts
module MyKernel
  PutsMutex = Mutex.new
  def puts(*)
    PutsMutex.synchronize{super}
  end
end

module Kernel
  prepend MyKernel
end
# Threadsafe `puts` that outputs text and newline atomically
def safe_puts(msg)
    puts msg + "\n"
end