2015-12-11 7 views
5

私は何百もの場所でコンソールに出力するマルチスレッドプログラムを持っています。残念ながら、代わりにputsをスレッドセーフにする

Line 2 
Line 1 
Line 3 

の私はputsスレッドを安全にしようとしています

Line2Line1 

Line3 

を取得します。

(私はこの問題を持っていると思うが、それがなかったと仮定していない)Pythonで

、私はRubyでこれをしようとしている

old_print = print 

print_mutex = threading.Lock() 

def print(*args, **kwargs): 
    print_mutex.acquire() 
    try: 
     old_print(*args, **kwargs) 
    finally: 
     print_mutex.release() 

を行いたい

old_puts = puts 

puts_mutex = Mutex.new 

def puts(*args) 
    puts_mutex.synchronize { 
     old_puts(*args) 
    } 

しかし、これは動作しません: "未定義のメソッドold_puts"


スレッドセーフ(スレッドセーフ)部分行を印刷しない)?

+4

ヒント: 'old_puts = puts'を実行すると、暗黙的に' old_puts = puts() 'を実行しています –

答えて

6
alias old_puts puts 

以上の近代的な方法:

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

module Kernel 
    prepend MyKernel 
end 
+2

" modern "= Ruby 2.0+ –

0

この現象の理由はputsが内部で二回基礎となるwrite関数を呼び出すことである - 実際の値が書き込まれるための1、およびへの改行のための1書かれている。あなたが書いている文字列に\nを追加します(Ruby's puts is not atomicで説明)

ここでは正確に一度putsコールwriteを作るためのハックです。ここでは、これは私のコードでは、次のようになります。

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

putsは内部的に書き込まれているオブジェクトは末尾の改行を持っているかどうかをチェックし、それが真でない場合にのみ、再びwriteを呼び出します。入力が改行で終わるように変更したので、putswriteへの呼び出しを1回だけ終了します。

関連する問題