91

What is exactly the function of Python's Global Interpreter Lock? Do other languages that are compiled to bytecode employ a similar mechanism?

Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
  • 6
    You should also ask "Does it even matter?" – S.Lott Nov 05 '08 at 20:18
  • 2
    I agree, I consider it a non-issue now that in 2.6 the multiprocessing module was added to allow you to program using multiple processes in a thread-like manner. http://docs.python.org/library/multiprocessing.html – monkut Nov 06 '08 at 01:16
  • What is the Gil: https://stackoverflow.com/questions/1294382/what-is-the-global-interpreter-lock-gil-in-cpython Related on Programmers: https://softwareengineering.stackexchange.com/questions/186889/why-was-python-written-with-the-gil – Ciro Santilli OurBigBook.com Mar 23 '19 at 07:38

5 Answers5

72

In general, for any thread safety problem you will need to protect your internal data structures with locks. This can be done with various levels of granularity.

  • You can use fine-grained locking, where every separate structure has its own lock.

  • You can use coarse-grained locking where one lock protects everything (the GIL approach).

There are various pros and cons of each method. Fine-grained locking allows greater parallelism - two threads can execute in parallel when they don't share any resources. However there is a much larger administrative overhead. For every line of code, you may need to acquire and release several locks.

The coarse grained approach is the opposite. Two threads can't run at the same time, but an individual thread will run faster because its not doing so much bookkeeping. Ultimately it comes down to a tradeoff between single-threaded speed and parallelism.

There have been a few attempts to remove the GIL in python, but the extra overhead for single threaded machines was generally too large. Some cases can actually be slower even on multi-processor machines due to lock contention.

Do other languages that are compiled to bytecode employ a similar mechanism?

It varies, and it probably shouldn't be considered a language property so much as an implementation property. For instance, there are Python implementations such as Jython and IronPython which use the threading approach of their underlying VM, rather than a GIL approach. Additionally, the next version of Ruby looks to be moving towards introducing a GIL.

Community
  • 1
  • 1
Brian
  • 116,865
  • 28
  • 107
  • 112
  • 1
    can you explain this : 'Two threads can't run at the same time'? Recently I wrote a simple webserver in Python with multithreading. For every new request from client, servers spawns off a new thread for it and those thread continue to execute. So there will be multiple threads running at the same time right? Or have I understood in wrong way? – avi Dec 02 '13 at 04:22
  • 1
    @avi AFAIK python threads can't run simultaneously, but that doesn't mean one thread must block the other. GIL only means that only one thread can interpret python code at one time, it doesn't mean that thread management and resource allocation doesn't work. – Benproductions1 Feb 06 '14 at 08:31
  • 2
    ^so at any time point of time, only one thread will be serving content to client... so no point of actually using multithreading to improve performance. right? – avi Feb 06 '14 at 10:34
  • And, of course, Java is compiled to byte code and allows very fine grained locking. – Warren Dew Apr 06 '14 at 09:48
  • 3
    @avi, an IO bound process like a webserver can still gain from Python threads. Two or more threads can do IO simultaneously. They just cant be interpreted (CPU) simultaneously. – Saish Apr 15 '15 at 16:11
  • @avi and anyone who wants to learn more about GIL, http://www.dabeaz.com/python/UnderstandingGIL.pdf – gokul_uf Mar 12 '16 at 07:36
35

The following is from the official Python/C API Reference Manual:

The Python interpreter is not fully thread safe. In order to support multi-threaded Python programs, there's a global lock that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.

Therefore, the rule exists that only the thread that has acquired the global interpreter lock may operate on Python objects or call Python/C API functions. In order to support multi-threaded Python programs, the interpreter regularly releases and reacquires the lock -- by default, every 100 bytecode instructions (this can be changed with sys.setcheckinterval()). The lock is also released and reacquired around potentially blocking I/O operations like reading or writing a file, so that other threads can run while the thread that requests the I/O is waiting for the I/O operation to complete.

I think it sums up the issue pretty well.

mdb
  • 52,000
  • 11
  • 64
  • 62
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • 1
    I read it too, but I can't understand why Python is different in this respect from, say, java (is it?) – Federico A. Ramponi Nov 05 '08 at 16:34
  • @EliBendersky Python threads are implemented as pthreads and are handled by the OS (http://www.dabeaz.com/python/UnderstandingGIL.pdf) whereas Java threads are application level threads whos scheduling is handled by the JVM – gokul_uf Mar 12 '16 at 07:40
20

The global interpreter lock is a big mutex-type lock that protects reference counters from getting hosed. If you are writing pure python code, this all happens behind the scenes, but if you embedding Python into C, then you might have to explicitly take/release the lock.

This mechanism is not related to Python being compiled to bytecode. It's not needed for Java. In fact, it's not even needed for Jython (python compiled to jvm).

see also this question

Community
  • 1
  • 1
David Nehme
  • 21,379
  • 8
  • 78
  • 117
  • 4
    "This mechanism is not related to Python being compiled to bytecode": Precisely, it's an artifact of the CPython implementation. Other implementations (like Jython that you've mentioned) can be free of this restriction by the virtue of their thread-safe implementation – Eli Bendersky Nov 05 '08 at 16:40
12

Python, like perl 5, was not designed from the ground up to be thread safe. Threads were grafted on after the fact, so the global interpreter lock is used to maintain mutual exclusion to where only one thread is executing code at a given time in the bowels of the interpreter.

Individual Python threads are cooperatively multitasked by the interpreter itself by cycling the lock every so often.

Grabbing the lock yourself is needed when you are talking to Python from C when other Python threads are active to 'opt in' to this protocol and make sure that nothing unsafe happens behind your back.

Other systems that have a single-threaded heritage that later evolved into mulithreaded systems often have some mechanism of this sort. For instance, the Linux kernel has the "Big Kernel Lock" from its early SMP days. Gradually over time as multi-threading performance becomes an issue there is a tendency to try to break these sorts of locks up into smaller pieces or replace them with lock-free algorithms and data structures where possible to maximize throughput.

Edward Kmett
  • 29,632
  • 7
  • 85
  • 107
  • +1 for mentioning the fact that coarse grained locking is used than most think, especially the oft-forgotten BKL (I use `reiserfs` - the only real reason I know about it at all). – new123456 Jul 07 '11 at 01:17
  • 3
    Linux had BKL, since version 2.6.39, BKL has been removed completely. – avi Dec 02 '13 at 08:35
  • 5
    Of course. Mind you that was ~3 years after I answered the question. =) – Edward Kmett Dec 08 '13 at 12:43
7

Regarding your second question, not all scripting languages use this, but it only makes them less powerful. For instance, the threads in Ruby are green and not native.

In Python, the threads are native and the GIL only prevents them from running on different cores.

In Perl, the threads are even worse. They just copy the whole interpreter, and are far from being as usable as in Python.

user3708642
  • 124
  • 10
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412