How about: def lock_call(mutex, func, *args, **kwargs): mutex.acquire() try: res = func(*args, **kwargs) finally: mutex.release() return res def do_something(blah): # do stuff m = threading.Lock lock_call(m, do_something, "some data")