tags:

views:

124

answers:

3

In python, I have a global variable defined that gets read/incremented by different threads. Because of the GIL, will this ever cause problems without using any kind of locking mechanism?

+2  A: 

Yes, multithreading without locking almost always causes problems, with or without a GIL.

Greg Hewgill
Note that the GIL isn't there to protect your application data; it's only there to protect some Python internal structures like the reference counts for Python objects. You still have to lock your structures.
S.Lott
Exactly. The GIL protects Python from itself, but it doesn't do anything to protect you.
Greg Hewgill
And of course the vast majority of Python execution engines don't even *have* a GIL.
Jörg W Mittag
+2  A: 

Short answer: Don't assume this to be safe. You have no guarantee that the implementation of the language won't change out from underneath you; for instance, your code could be running on Stackless, or Jython, or IronPython at some point in the future. Assuming the GIL will take care of this (i.e. the implementation implies the GIL is present) means that you will, at some point, have something break.

Avery Payne
+4  A: 

The GIL only requires that the interpreter completely executes a single bytecode instruction before another thread can take over. However, there is no reason to assume that an increment operation is a single instruction. For example:

>>> import dis
>>> dis.dis(compile("x=753","","exec"))
  1           0 LOAD_CONST               0 (753)
              3 STORE_NAME               0 (x)
              6 LOAD_CONST               1 (None)
              9 RETURN_VALUE
>>> dis.dis(compile("x+=1","","exec"))
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (1)
              6 INPLACE_ADD
              7 STORE_NAME               0 (x)
             10 LOAD_CONST               1 (None)
             13 RETURN_VALUE

As you can see, even these simple operations are more than a single bytecode instruction. Therefore, whenever sharing data between threads, you must use a separate locking mechanism (eg, threading.lock) in order to maintain data consistency.

Daniel G
Ouch. I mean, 3 upvotes and nobody noticed the `dis.dis("x=753")` output? I corrected the code.
ΤΖΩΤΖΙΟΥ
Here's an example where I should be paying more attention to what I'm writing - thank you :). Also, it displays the point even more clearly - after loading the value, there are *several* instructions before the value is stored again.
Daniel G