2015-12-11 4 views
5

मेरे पास एक बहुप्रचारित प्रोग्राम है जो सैकड़ों स्थानों पर कंसोल पर प्रिंट करता है। दुर्भाग्य से,रखो थ्रेड-सुरक्षित

Line 2 
Line 1 
Line 3 

के बजाय मैं

Line2Line1 

Line3 

मिल रहा puts धागा सुरक्षित बनाने की कोशिश कर रहा हूँ।


अजगर (जो मुझे नहीं लगता कि इस समस्या है, लेकिन यह किया था लगता है) में, मैं

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

" आधुनिक "= रूबी 2.0+ कर रहे हैं –

0

इस व्यवहार के लिए कारण यह है कि puts आंतरिक रूप से दो बार अंतर्निहित write फ़ंक्शन को कॉल है - के लिए वास्तविक मूल्य लिखा होना चाहिए एक है, और करने के लिए न्यू लाइन के लिए एक लिखा जाना (Ruby's puts is not atomic में समझाया)

यहाँ एक हैक है puts कॉल write ठीक एक बार बनाने के लिए: स्ट्रिंग आप लिख रहे हैं करने के लिए \n जोड़ें। यहां बताया गया है कि यह मेरा कोड में की तरह लग रहा है:

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

puts आंतरिक रूप से जाँच करता है वस्तु लिखा जा रहा अंत में एक नई पंक्ति है या नहीं, और केवल फिर से write कॉल करता है, तो यह सच नहीं है। चूंकि हमने इनपुट को एक नई लाइन के साथ बदल दिया है, putswrite पर केवल एक कॉल करने के समाप्त होता है।

संबंधित मुद्दे