2015-12-11 25 views
5

Yüzlerce yerde konsola yazdıran çok iş parçacıklı bir programım var. Ne yazık ki, yerineİş parçacığı güvenli hale getirme

Line 2 
Line 1 
Line 3 

I

Line2Line1 

Line3 

olsun ben puts parçacığı güvenli hale getirmek için çalışıyorum.

(Ben bu sorunu olduğunu düşünüyorum, ama o did sanmıyorum) Python

, ben Ruby bu çalışıyorum

old_print = print 

print_mutex = threading.Lock() 

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

, yapardım

old_puts = puts 

puts_mutex = Mutex.new 

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

Ama bu işe yaramazsa: "tanımsız yöntemi old_puts"


İplik güvenliğini nasıl sağlayabilirim (ör. kısmi çizgiler yazdırmak değil)?

+4

İpucu: 'old_puts = puts 'yaptığınız zaman örtük olarak yapıyorsunuz' old_puts = koyar()' –

cevap

6
alias old_puts puts 

ya da daha modern bir yol:

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

module Kernel 
    prepend MyKernel 
end 
+2

"modern" = Ruby 2.0+ –

0

Bu davranışın nedeni puts içten iki kez yatan write işlevini çağırır olmasıdır - gerçek değer yazılacak için bir ve karşı Yenisatır için bir yazılacak. Yazdığınız dizeye \n ekle:

Burada yalnızca bir kez puts çağrı write yapmak için bir hack var (Ruby's puts is not atomic) maddesinde açıklanmıştır. İşte bu benim kodunda şu şekilde görünür:

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

puts içten yazılıyor nesne sonunda bir yeni satır olup olmadığını denetler ve bu doğru değilse, sadece tekrar write çağırır. Girişi bir satırsonuyla sonlandırdığımızdan beri, puts, yalnızca bir aramayı write'a getiriyor.

İlgili konular