3 ms·
Previously people basically didn't bother to write multithreaded Python at all due to the GIL. Threads were primarily used when you had multiple pieces of work
by dathery 3y ago
Previously people basically didn't bother to write multithreaded Python at all due to the GIL. Threads were primarily used when you had multiple pieces of work to do which could end up blocked on independent I/O. Which is common and useful of course, but doesn't help with the performance of CPU-bound Python code.
Even outside of high-intensity CPU work, this can be useful. A problem lately is that a lot of code is written using Python's native asyncio language features. These run single-threaded with async/await to yield execution, much like in NodeJS, and can achieve pretty good throughput even with a single thread (thousands of reqs/second).
However, a big problem is that any time you do _any_ CPU work, you block all other coroutines, which causes all kinds of obscure issues and ruins your reqs/second. For example, you might see random IO timeouts in one coroutine which are actually caused by a totally different coroutine hogging the CPU for a bit. It can be very hard to get observability into why this is happening. asyncio provides a `asyncio.to_thread()` function [1] which can help to take blocking work off the main thread, but because of the GIL it doesn't truly allow the CPU-bound to avoid interfering with other coroutines.
[1] https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread https://docs.python.org/3/library/asyncio-task.html#asyncio....
- hsbauauvhabzb 3y agoWill this also support threads spanning multiple cores, or is that unrelated? Edit: https://peps.python.org/pep-0703/ https://peps.python.org/pep-0703/ suggests it will support multiple cores, unless the current work does not yet achieve that.
- fireattack 3y agoWould GIT affect how Python runs across multiple Python processes? I'm asking because I encountered a weird phenomenon before. I use a simple Python lib called "schedule" which is to run some tasks periodically (not precise). And I often run a script multiple times (with different arguments) to monitor something say, every 30 seconds. So they're in three separate Python Interpreter processes. What I've noticed is that while when I initiated them, they were something like 5 seconds apart, they eventually will end up running in sync. Probably not related to GIL at all, but I guess do no harm to ask.
- Austizzle 3y agoThe GIL is per interpreter/process, so this wouldn't be related as far as I know. The GIL only really kicks in if you use threads in a single process. Then, the GIL will only let one single thread do actual work at a time, and will trade off which thread gets to do work. The other threads can wait on IO stuff (web requests, the file system, etc) but they can't do number crunching or data processing at the same time. That's a really interesting observation though, I wonder what _is_ causing your separate processes to sync up?
- refibrillator 3y agoI’ve seen this before! Indeed it has nothing to do with Python or the GIL. The OS scheduler has to execute M threads on N cpu cores, while also balancing competing priorities like latency and power usage. Because each separate process uses a naive timer, the timings will drift slowly due to imprecision and small process scheduling delays etc. After enough drift the timers will sync up by chance (harmonics), at which point OS scheduler incentives can lead the timings to “stick” together seemingly. This may be a bit tangential, but I find it fascinating that there seems to be a mechanical version of this phenomenon with ancient roots - lookup spontaneous synchronization of pendulums.
- fireattack 3y agoThank you for your insight! By the way, I asked about it previously on their repo before, if you're interested. No replies yet though, since the development of the lib isn't very active to begin with. https://github.com/dbader/schedule/issues/614 https://github.com/dbader/schedule/issues/614