Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Sorry, stupid question, can someone tell, please, how do other interpreted languages deal with problem similar to GIL or noGIL?


You use smaller scale locks as and when you need them, and you spend a lot of time to carefully implement core threading constructs and similar to make sure they are correct.

Most of the time in an interpreter you’re iterating through the byte code for a function, and mutating variables. It doesn’t matter if two threads are executing that same byte code, it only matters if they are mutating the same object.

That’s not to say there aren’t some operations that need coordination across all threads. For that you implement safe points so you signal that something has to be done, wait for all threads to reach a safe point, do the work, and then release the threads again. You can often be even smarter about this and avoid stopping all threads at once but instead stagger things.

Allocation and GC you can make more thread local to avoid stopping the world too often.


Bytecode vs JIT doesn't really make a difference. But taking to question to managed languages (so Python, Erlang, JS, Ruby, .NET, JVM etc) - there isn't really a GIL problem to start with in language design, there's just design choices wrt what, if anything, to do about parallelism/concurrency. For example Erlang and recent browser Javascript skip shared memory parallelism and use message passing (JS web workers and Erlang processes). Python's approach is motivated by it's simple refcount-based garbage collection, other GCs have it easier.


Ruby [1], JavaScript (when running in NodeJS) and PHP are single-threaded. Perl is single threaded as well but it features something like to what is being proposed in PEP 554 (https://peps.python.org/pep-0554/).

I know Clojure is often described as a dynamic language and that it has some concurrency primitives, but my knowledge ends here.

[1] Just like Python, Ruby does have implementations that allow multi-threading.


Ruby is not single threaded even in its default implementation, but it does have a global value lock that is equivalent to the GIL. Not only does it have threads, it also has fibers which allow for more cooperative scheduling.


The GIL is a conscious trade-off between contention/performance against a simpler code.

Without the GIL, you'd still need to use different locking/synchronization mechanisms to ensure thread safety (if required), but they'd be more nuanced and spread over the entire codebase (complicating the backend).


I think comparing it to something like nodejs the way they work around the issue is that almost all their code is written in JavaScript itself. Python has a different model where a very large amount of the code is written in c and python itself is just a glue.


A huge amount of NodeJS is written in native code. JS is single threaded. Async work doesn’t work without native code. JS doesn’t need a GIL because it only has one thread.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: