2

I have one server with 10 cpu cores, when I ran the following code which one thread, one of the cpu cores usage was 100%:

def fun():
    while 1:
        pass

but when I use 5 threads to run the same code, there were 5 cpu cores usages were: 30%, 20%, 15%, 25%, 12% respectively.

Why were not 5 cpu cores with 100% usages respectively? If multiple python threads can not fully use CPUs, how should multiple thread is faster than one thread?

Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
Jack
  • 5,540
  • 13
  • 65
  • 113
  • 2
    This is probably because of the [Global Interpreter Lock](https://wiki.python.org/moin/GlobalInterpreterLock). Depending on your problem, you might be able to get around it by using `multiprocessing`. – mgilson Sep 06 '15 at 01:45

1 Answers1

4

What you described is the typical bottleneck, which becomes more present when more cores try to get access to a single lock. As mgilson mentioned, this is the side-effect of the GIL which exists in many implementations of Python. The GIL in Python guarantees that only one thread executes Python byte-code at a time. This is for historical reasons. But as Roland also mentioned in the comments, the GIL makes e.g. debugging of the garbage collector much easier. There are implementations like IronPython which don't have a GIL though.

Python 2 and Python 3 have different approaches how a thread acquires the GIL.

Python 2: http://www.dabeaz.com/python/GIL.pdf

Python 3: http://www.dabeaz.com/python/NewGIL.pdf

One solution is to spawn independent Python interpreters. They work as separate processes and can do their own work. The multiprocessing module can help you here.

HelloWorld
  • 2,392
  • 3
  • 31
  • 68
  • "One solution to **avoid**"? Probably you meant "one possible solution". – Andrea Corbellini Sep 06 '15 at 17:02
  • I edited the answer, I believe @AndreaCorbellini is correct. – A. Jesse Jiryu Davis Sep 06 '15 at 17:09
  • Those historical reasons were and still are extremely *practical* and *valid*. Having the GIL makes the garbage collection code a lot simpler (it is not thread-safe, but would have to be so without the GIL). The desire to remove the GIL has come up several times, but no one has managed it, [for several reasons](https://wiki.python.org/moin/GlobalInterpreterLock). – Roland Smith Sep 06 '15 at 17:29
  • AndreaCorbellin is right, yes, but next time give the OP please some time. I prefer to correct my answer on my own. The fastest gun in the west does also apply on editing. @RolandSmith: That's true. I didn't want to imply the GIL is just bad. I added this to my answer. – HelloWorld Sep 06 '15 at 17:32