python + wsgi on a multi-threaded web-server: is this a race condition? python + wsgi on a multi-threaded web-server: is this a race condition? multithreading multithreading

python + wsgi on a multi-threaded web-server: is this a race condition?


Yes, you have a race condition there, but it's not related to the imports. The global state in foo.a is subject to a data race between a + 1 and a = ...; since two threads can see the same value for a, and thus compute the same successor.

The import machinery itself does protect against duplicate imports by multiple threads, by means of a process wide lock (see imp.lock_held()). Although this could, in theory, lead to a deadlock, this almost never happens, because few python modules lock other resources at import time.

This also suggests that it's probably safe to modify sys.path at will; since this usually happens only at import time (for the purpose of additional imports), and so that thread is already holds the import lock, other threads cannot cause imports that would also modify that state.

Fixing the race in racer() is quite easy, though:

import threadinga = 1a_lock = threading.Lock()def racer():    global a    with a_lock:        my_a = a = a + 1    return str(my_a)

which will be needed for any global, mutable state in your control.


Read the mod_wsgi documentation about the various processes/thread configurations and in particular what it says about data sharing.

In particular it says:

Where global data in a module local to a child process is still used, for example as a cache, access to and modification of the global data must be protected by local thread locking mechanisms.