3

I recently came across the GIL present in Python according to which only a single thread can execute at a time and multithreading can not utilize all the cores.

Now in one of my projects, I used multithreading and lots of locks and semaphores So here my question is can I achieve the same thing if I don't use locks and semaphores? i.e if I remove the concurrency logics from my project.

Edit: What I want to know is, whether it's possible to attain same functionality if I remove concurrency logics, I know what is GIL and it prevents threads to use all the cores and only one thread is run at a time.

7
  • If it helps, Project isn't I/O bound, its CPU Intensive. Commented Sep 14, 2017 at 5:15
  • check this link :stackoverflow.com/questions/11277784/… Commented Sep 14, 2017 at 5:22
  • @AmitGupta It doesn't answer my question i.e Is there still a need to protecting the shared resources using locks and semaphores if all the threads are not running at the same time because of the presence of GIL. Commented Sep 14, 2017 at 5:28
  • 1
    @VINAYCHAUHAN Yes, if you have multiple threads and shared resources you must still serialise access to them using mutexes even in the presence of the Global Interpreter Lock Commented Sep 14, 2017 at 5:39
  • 1
    You never know when you will loose the GIL, it could be mid-way between an operation that consists of several byte-code instructions. Commented Sep 14, 2017 at 5:48

1 Answer 1

4

The Global Interpreter Lock ensures that only one thread is executing byte code at once. That execution could be interrupted at any time.

Consider this simple function which might be intended to atomically store related values to attributes on an instance x

def f(x, a, b): x.a, x.b = a, b 

Here is its disassembly into bytecode

 0 LOAD_FAST 1 (a) 3 LOAD_FAST 2 (b) 6 ROT_TWO 7 LOAD_FAST 0 (x) 10 STORE_ATTR 0 (a) 13 LOAD_FAST 0 (x) 16 STORE_ATTR 1 (b) 19 LOAD_CONST 0 (None) 22 RETURN_VALUE 

Suppose x is not protected by a mutex. Then any thread executing f(x, 1, 2) can easily be interrupted between storing a (at 10) and storing b (at 16). That interrupting thread will now see x in an inconsistent state.

Sign up to request clarification or add additional context in comments.

6 Comments

So you are trying to say GIL doesn't switch the thread if it is holding a lock btw your answer does clear things for me.
@VINAYCHAUHAN No, I'm not saying that. The GIL will still attempt to switch thread ... but if you were using a mutex to protect x, which the original thread has acquired, then the new switched in thread cannot possibly acquire that mutex and see x in an inconsistent state.
Well, I believe then it's a bigger problem, suppose I have 100s of threads and each accessing the same resource, now if there is a context switch while the thread holds a mutex then the whole program (all the threads) block till the context changes to the original thread and the lock is released.
@VINAYCHAUHAN Surprisingly, you might find the python developers have thought of this ... the GIL only applies to code interpreting bytecode. A mutex acquire is C-code that does not require the GIL. The new thread, upon attempting to acquire the mutex will block in C-code, relasing the GIL to another thread. You have not suddenly discovered a massive hole in python thread design that no one has noticed in the last decade.
@donkopotamus I think to prevent the problem you mentioned in the example, we have GIL. Since in the case of GIL the complete assembly block will be part of locking and unlocking sequence.I think that GIL wouldn't allow any inconsistency, except in the case where you are killing the whole program altogether, which I guess no locking semantics in the world could prevent.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.