5 ms·
I've been bitten by the GIL multiple times since switching to a company writing mostly python. Not that I write that much multithreaded code, but the GIL influe
by matsemann 5y ago
I've been bitten by the GIL multiple times since switching to a company writing mostly python. Not that I write that much multithreaded code, but the GIL influences everything so lots of patterns in other languages no longer work.
For instance, a local cache of some values is basically useless when python is used as backend. Since there will be multiple processes handling the requests (in the same node), they don't share memory. So basically everything has to be stashed at redis. Of course, with scale and multiple nodes lots of stuff should be cached in redis anyway. But not everything makes sense to reach out to an external service for. Like fetching a token I need to use multiple times, instead if having it stored locally in a variable. There are of course ways around this, using some locally shared file or mmap or whatever, but it's a hassle compared to just setting a variable.
Same with background tasks or spinning up extra threads to handle the workload of an incoming request. Can't easily be done, so basically every python project includes celery or something similar. Which works fine, but again, a different and forced way to solve something.
Asyncio solves many of the daily problems I would have used threads for, though. As I often used it other places to fire off some http requests to other services in parallel. But unfortunately async doesn't work properly with everything yet.
So everything has a solution, but you are forced to do it "the python way" and with some hurdles.
- pjmlp 5y agoWhat about doing it the UNIX way before pthreads became a thing?
- gpderetta 5y agoWell, yes, but there is a reason why pthreads became a thing.
- pjmlp 5y agoUntil people discovered the security and program stability issues that come with using them. It was a cool idea that turned out not so be so great after all. There is a reason why all major language runtimes are moving into thread agnostic runtimes, while security critical software and plugins are back into processes with OS IPC model.
- gpderetta 5y agoSorry, which languages? Go has shared memory multiprocessing, so does Rust, C#, Java...
- pjmlp 5y agoThey do, and in all of them is an anti-pattern to use raw threads instead of the higher level frameworks like goroutines, java.util.concurrent or TPL/DataFlow. Go in their typical wisdom, doesn't even support thread local storage. Additionally, Java and .NET have thrown away their security managers, and guess what is the best practice to regain their features in Java and .NET applications? Multi-processing with OS IPC.
- gpderetta 5y agoSorry, we are discussing shared memory multiprocessing. I'm certainly not advocating unrestricted use of pthread_create, but even more structured way of parallelization still rely on shared memory. But of course, for security address space separation is pretty much a requirement.
- Jweb_Guru 5y agoIt's not an antipattern to use threads in Rust. Where did you get that idea?
- dragonwriter 5y ago> For instance, a local cache of some values is basically useless when python is used as backend. Since there will be multiple processes handling the requests (in the same node), they don’t share memory. Obviously, you can choose to do it that way, but there is no reason that multiple processes can’t share memory in Python; there is, in fact, explicit support for this in the standard library.
- BlackFly 5y agoThis is perhaps the most difficult aspect about discussions involving the GIL, the level of nitpicking while ignoring the actual point when someone feels that python is being slighted. > you can choose to do it that way, but there is no reason that multiple processes can’t share memory in Python; there is, in fact, explicit support for this in the standard library. Yes, and you can also just use threads and directly go shared memory so you are not literally "forced", you are forced because the choice comes with a cost you don't want to pay. Depending on the OS for managing shared memory and using an API isn't much different from using a sidecar process and has its own cost over native shared memory model. In the end, most engineers will choose and have chosen redis or memcached over the alternatives. The GIL is still a huge factor in these decisions.
- BlackFly 5y agoIt's really a shame you are getting down voted. You are basically just saying, "Sometimes shared memory model makes a more efficient and simpler solution over enforced actor model. Like in this case." This shouldn't be controversial, engineering choices come with tradoffs and the GIL certainly pushes you for making a specific choice. Yes, if you are going to be doing caching in python, you are almost certainly going to be caching it in a separate service and serializing across process boundaries. If you are going to be holding onto a connection pool as well (PG bouncer being the most typical). More generally, any sort of shared resource that would require or benefit strongly from shared memory model needs to be pushed into a sidecar service written in a language that actually supports efficient shared memory model. These are precisely the sorts of problems that the GIL causes. There are standard ways to work around it and most python developers can reach for these solutions, but this is not a contradiction to the fact that the GIL has limited your choice in the matter.
- dragonwriter 5y ago> It’s really a shame you are getting down voted. You are basically just saying, “Sometimes shared memory model makes a more efficient and simpler solution over enforced actor model. Like in this case.” If he was just saying that, he’d probably be downvoted for being true but irrelevant and not meaningfully contributing. But he’s actually saying that plus “therefore, Python is bad (implying that Python can’t use shared memory between processes).” Which would be a productive, relevant contribution except for the fact that it’s not true. > More generally, any sort of shared resource that would require or benefit strongly from shared memory model needs to be pushed into a sidecar service written in a language that actually supports efficient shared memory model. That’s I guess technically true, if you included the stdlib modules which directly support this and are themselves written in (I assume) C. But, “you might have to use the standard library” is…not much of an impediment.
- BlackFly 5y agoNo, he is making the useful observation that the GIL has an impact on system architecture. That is why typically python webservers run in multiprocess mode but Java (for example) webservers typically runs in threaded mode.
- BiteCode_dev 5y ago> For instance, a local cache of some values is basically useless when python is used as backend. Since there will be multiple processes handling the requests (in the same node), they don't share memory. If you want to share low level memory between process, use SharedMemory: https://docs.python.org/3/library/multiprocessing.shared_memory.html https://docs.python.org/3/library/multiprocessing.shared_mem... If you want to share high level data structure between process, use diskcache: http://www.grantjenks.com/docs/diskcache/tutorial.html http://www.grantjenks.com/docs/diskcache/tutorial.html This is, granted, not as straightforward as just sharing a variable between threads, but it will get you far.
- goldenkey 5y agoThat's like claiming the ability to share JS ArrayBuffer's between workers supplants the need for the ability to share high level objects like a Map. What I'm getting at is that JS had the exact same problem, and it offers the same ability for sharing blocks of raw memory. But the same pitfalls for any actual structured object. Instead, we have to serialize/unserialize (creating a copy) from a separate worker, process, or disk source, it's performance is shite for objects of large size. Message passing is not ideal for large pieces of data. Shared memory is hundreds of times faster.
- BiteCode_dev 5y agoYes. SharedMemory can share list (https://docs.python.org/3/library/multiprocessing.shared_memory.html#multiprocessing.shared_memory.ShareableList https://docs.python.org/3/library/multiprocessing.shared_mem...) but that's it. That's why diskscache is better as an alternative for complex objects: https://pypi.org/project/diskcache/ https://pypi.org/project/diskcache/ It's not as good as a simple shared variable, but it's surprisingly performant, since it uses memory-mapped files.
- goldenkey 5y agoI see what you mean. Does diskcache still have to do deserialization of the mapped data? Nested objects (large disparate heap pointer graphs) would suffer performance penalties.
- tored 5y agoI have to ask, what is then the point of using Python as a backend (not questioning for data crunching)? Funny thing here is that PHP works exactly the same with its share nothing architecture. You always need to go outside of PHP handle state between requests. When I started doing PHP years ago this was one of the first things I stumbled upon on, used to being able to easily share state in a backend. Juniors or non-programmers does usually not think about this at all and thus is not limited by it, whereas programmers with experience from another language, but without any deep PHP knowledge, will always trip up on this, finding it awkward and annoying (like I did). And yes, the share nothing architecture will change how you write programs. Now many years later I'm used to this and don't see it as problem anymore (almost the opposite). But if you also need to follow the share nothing architecture on Python, what benefits does it give vs PHP? Is it the community only? Because Python is generally slower than PHP. I don't consider myself as a Python developer, but based on my knowledge I have hard time finding compelling arguments for picking Python as (web) backend. I rather pick PHP (I have bias), Golang or Java. Nodejs vs Python it a tough one, perhaps nodejs because I can write in TypeScript, but nodejs is not a technology I like.
- miohtama 5y ago> the share nothing architecture on Python, what benefits does it give vs PHP A programming language with better ergonomics, developer experience and more mature community.
- tored 5y agoHow does Python have better ergonomics? Better developer experience for Python is probably true, more mature community I can't say either way. Edit: One thing that would be nice in PHP is decorators.
- guggle 5y ago> Edit: One thing that would be nice in PHP is decorators. 15 years I used to say "I wish PHP had feature X just like in language Y". But there's a moment where it's better not to wait and just to use language Y.
- zzzeek 5y agoasyncio doesn't solve any "problems" of threads in Python. it just provides programming patterns that a lot of people like, which are well suited towards having hundreds or thousands of arbitrarily slow IO bound tasks at once. A threadpool in Python can do the same thing with mostly similar performance. asyncio certainly isn't affecting the GIL issue, asyncio is "GIL-ish" by definition since all CPU work occurs in a single thread. meaning, if the GIL were removed from Python, the performance of threaded concurrency would soar, asyncio would not move an inch.
- matsemann 5y agoIt "solves" the problem of me having to do five calls in parallel. They can with asyncio in theory be done at the same time, since python can move on and fire off the next calls while waiting for IO.