Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper use of mutexes in Python

I am starting with multi-threads in python (or at least it is possible that my script creates multiple threads). would this algorithm be the right usage of a Mutex? I haven't tested this code yet and it probably won't even work. I just want processData to run in a thread (one at time) and the main while loop to keep running, even if there is a thread in queue.

from threading import Thread from win32event import CreateMutex mutex = CreateMutex(None, False, "My Crazy Mutex") while(1)     t = Thread(target=self.processData, args=(some_data,))     t.start()     mutex.lock()  def processData(self, data)     while(1)         if mutex.test() == False:             do some stuff             break 

Edit: re-reading my code I can see that it is grossly wrong. but hey, that's why I am here asking for help.

like image 924
Richard Avatar asked Jul 22 '10 14:07

Richard


People also ask

Why do we need mutexes?

Mutex or Mutual Exclusion Object is used to give access to a resource to only one process at a time. The mutex object allows all the processes to use the same resource but at a time, only one process is allowed to use the resource. Mutex uses the lock-based technique to handle the critical section problem.

When would you use a mutex lock?

Mutex: Use a mutex when you (thread) want to execute code that should not be executed by any other thread at the same time.

How do mutexes work?

Mutex lock will only be released by the thread who locked it. So this ensures that once a thread has locked a piece of code then no other thread can execute the same region until it is unlocked by the thread who locked it.

How do you implement a lock in Python?

A lock can be locked using the acquire() method. Once a thread has acquired the lock, all subsequent attempts to acquire the lock are blocked until it is released. The lock can be released using the release() method. Calling the release() method on a lock, in an unlocked state, results in an error.


2 Answers

I don't know why you're using the Window's Mutex instead of Python's. Using the Python methods, this is pretty simple:

from threading import Thread, Lock  mutex = Lock()  def processData(data):     mutex.acquire()     try:         print('Do some stuff')     finally:         mutex.release()  while True:     t = Thread(target = processData, args = (some_data,))     t.start() 

But note, because of the architecture of CPython (namely the Global Interpreter Lock) you'll effectively only have one thread running at a time anyway--this is fine if a number of them are I/O bound, although you'll want to release the lock as much as possible so the I/O bound thread doesn't block other threads from running.

An alternative, for Python 2.6 and later, is to use Python's multiprocessing package. It mirrors the threading package, but will create entirely new processes which can run simultaneously. It's trivial to update your example:

from multiprocessing import Process, Lock  mutex = Lock()  def processData(data):     with mutex:         print('Do some stuff')  if __name__ == '__main__':     while True:         p = Process(target = processData, args = (some_data,))         p.start() 
like image 53
Chris B. Avatar answered Sep 20 '22 21:09

Chris B.


This is the solution I came up with:

import time from threading import Thread from threading import Lock  def myfunc(i, mutex):     mutex.acquire(1)     time.sleep(1)     print "Thread: %d" %i     mutex.release()   mutex = Lock() for i in range(0,10):     t = Thread(target=myfunc, args=(i,mutex))     t.start()     print "main loop %d" %i 

Output:

main loop 0 main loop 1 main loop 2 main loop 3 main loop 4 main loop 5 main loop 6 main loop 7 main loop 8 main loop 9 Thread: 0 Thread: 1 Thread: 2 Thread: 3 Thread: 4 Thread: 5 Thread: 6 Thread: 7 Thread: 8 Thread: 9 
like image 25
Richard Avatar answered Sep 20 '22 21:09

Richard