Making a Queue for a function so it only runs once at a time in python
Question: I have a multithreaded function, which all write to the same log file. How can
I make this function (maybe with a function decorator) to add the execution of
writing to the log file to a queue. Small example:

    
    
    #!/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()
    

How can I make this function writeToLog add to a queue when executed? Now I
get every time both threads call the writeToLog function an error because the
other writeToLog function (from the other thread) already closed the file.
When having a global variable for this writer, which is closed in the end, I
get output like this:

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

And the output I always want has to look like this:

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


Answer: Concurrency access to a shared resource is a well known problem. Python thread
provide some mechanism to avoid issues. Use python locks :
<http://docs.python.org/2/library/threading.html#lock-objects> Lock are used
to synchronize access to a shared resource :

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

More information : <http://effbot.org/zone/thread-synchronization.htm>

Search for "Python synchronization"

