2013-08-20 13 views
0

我有一個多線程函數,它們都寫入同一個日誌文件。我怎樣才能使這個函數(也許用一個函數裝飾器)將寫入日誌文件的執行添加到隊列中。 小例子:爲一個函數建立一個隊列,所以它只能在Python中一次運行一次

#!/usr/bin/python 

import thread 
import time 

# Define a function for the thread 
def print_time(threadName, delay): 
    count = 0 
    while count < 5: 
     time.sleep(delay) 
     count += 1 
     writeToLog(threadName, time.ctime(time.time())) 
     print "%s: %s" % (threadName, time.ctime(time.time())) 

# Create two threads as follows 
try: 
    thread.start_new_thread(print_time, ("Thread-1", 2,)) 
    thread.start_new_thread(print_time, ("Thread-2", 4,)) 
except: 
    print "Error: unable to start thread" 

def writeToLog(threadName, time): 
    self.fileWriter = open("log.txt", "w") 
    self.fileWriter.write("ThreadName: " + threadName + "\n") 
    self.fileWriter.write("Time: " + time + "\n") 
    self.fileWriter.close() 

我怎樣才能讓執行時該功能writeToLog添加到隊列中?現在每當兩個線程都調用writeToLog函數時出錯,因爲其他writeToLog函數(來自其他線程)已經關閉了該文件。有這個作家,這是在結束時關閉一個全局變量的時候,我得到的輸出是這樣的:

ThreadName: thread1 
ThreadName: thread2 
Time: 9:50AM 
Time: 9:50AM 

和輸出我總是想有這樣的:

ThreadName: Thread-1 
Time: 9:50AM 
ThreadName: Thread-2 
Time: 9:50AM 
+3

爲什麼不使用python'logging',這是設計成線程安全的? –

+0

@RapolasK。我是python的新手,從來沒有見過這個模塊,看起來相當方便。我想我現在將使用這個模塊而不是我自己的類。謝謝! – Jetse

回答

2

併發訪問共享資源是一個衆所周知的問題。 Python線程提供了一些機制來避免問題。 使用Python鎖:http://docs.python.org/2/library/threading.html#lock-objects 鎖用於同步訪問共享資源:

lock = Lock() 

lock.acquire() # will block if lock is already held 
... access shared resource 
lock.release() 

的更多信息:http://effbot.org/zone/thread-synchronization.htm

搜索 「巨蟒同步」

+0

謝謝,這是我的問題的正確答案,所以我會接受這個答案。但是我現在要使用日誌記錄模塊。 – Jetse

+0

'Lock'實例是一個[上下文管理器](http://docs.python.org/2/library/threading.html?highlight=context%20manager#using-locks-conditions-and-semaphores-in-the -with-statement),它允許你用'lock'編寫''然後''訪問共享資源'而沒有別的東西。當退出縮進塊時,'release()'會自動發生,即使發生異常是因爲發生異常或執行了'return'語句。 – martineau

相關問題