Hey, I've been developing professionally with Python for 20 years, so wanted to weigh in: Decent threading is awesome news, but it only affects a small minority of use cases. Threads are only strictly necessary when it's prohibitive to message pass. The Python ecosystem these days includes a playbook solution for literally any such case. Considering the multiple major pitfalls of threads (i.e., locking), they are lik…
I haven’t been using it that much longer than you, and I agree with most of what you’re saying, but I’d characterize it differently. Python has a lot of solid workarounds for avoid threading because until now Python threading has absolutely sucked. I had naively tried to use it to make a CPU-bound workload twice as fast and soon realized the implications of the GIL, so I threw all that code away and made it multiproc…
The first year of free-threaded Python
281–290 of 302 posts
Re: The first year of free-threaded Python
#282Earlier quoted context omitted.
There's already a global: import gc gc.disable() So I imagine putting more in there to remove objects from the tracking.
That can go a long way, so long as you remember to manually GC the handful of things you do care about.
At least the objects get instantiated automatically, and you don't need to malloc() them into existence yourself; I guess that's still something.
Re: The first year of free-threaded Python
#283> Instead, many reach for multiprocessing, but spawning processes is expensive Agreed. > and communicating across processes often requires making expensive copies of data SharedMemory [0] exists. Never understood why this isn’t used more frequently. There’s even a ShareableList which does exactly what it sounds like, and is awesome. [0]: https://docs.python.org/3/library/multiprocessing.shared_mem...
Spawning processes generally takes much less than 1 ms on Unix Spawning a PYTHON interpreter process might take 30 ms to 300 ms before you get to main(), depending on the number of imports It's 1 to 2 orders of magnitude difference, so it's worth being precise This is a fallacy with say CGI. A CGI in C, Rust, or Go works perfectly well. e.g. sqlite.org runs with a process PER REQUEST - https://news.ycombinator.com/it…
Re: The first year of free-threaded Python
#284Earlier quoted context omitted.
Unix is not the only platform though (and is process creation fast on all Unices or just Linux?) The point about interpreter init overhead is, of course, apt.
Process creation should be fast on all Unices. If it isn't, then the lowly shell script (heavily used in Unix) is going to perform very poorly.
Re: The first year of free-threaded Python
#285Earlier quoted context omitted.
> But a thread can still crash in its own due to unhandled oom, assertion failures or any number of other issues That's not really true on POSIX. Unless you're doing nutty things with clone(), or you actually have explicit code that calls pthread_exit() or gettid()/pthread_kill(), the whole process is always going to die at the same time. POSIX signal dispositions are process-wide, the only way e.g. SIGSEGV kills a s…
It would be nice if someday we got per-thread signal handlers to complement per-thread signal masking and per-thread alternate signal stacks.
You can do all sorts of weird things like create threads which don't share file descriptors, threads which chdir() independently... except that CLONE_THREAD|~CLONE_SIGHAND and CLONE_SIGHAND|~CLONE_VM are disallowed.
Re: The first year of free-threaded Python
#286Earlier quoted context omitted.
> That's the trade-off. Personally I think a single digit percentage slow-down of single-threaded code worth it. Maybe. I would expect that 99% of python code going forward will still be single threaded. You just don’t need that extra complexity for most code. So I would expect that python code as a whole will have worse performance, even though a handful of applications will get faster.
That's the mindset that leads to the funny result that `uv pip` is like 10x faster than `pip`. Is it because Rust is just fast? Nope. For anything after resolving dependency versions raw CPU performance doesn't matter at all. It's writing concurrent PLUS parallel code in Rust is easier, doesn't need to spawn a few processes and wait for the interpreter to start in each, doesn't need to serialize whatever shit you wan…
Re: The first year of free-threaded Python
#287Earlier quoted context omitted.
Software rots, software tools evolve. When Intel released performance primitives libraries which required recompilation to analyze multi-threaded libraries, we were amazed. Now, these tools are built into processors as performance counters and we have way more advanced tools to analyze how systems behave. Older code will break, but they break all the time. A language changes how something behaves in a new revision, s…
My only concern is this kind of change in semantics for existing syntax is more worthy of a major revision than a point release.
Re: The first year of free-threaded Python
#288Earlier quoted context omitted.
> Does free-threaded Python provide the same guarantees Mostly. Some of the "can be pre-empted on the boundary between any two bytecode instructions" bugs are really hard to hit without free-threading, though. And without free-threading people don't use as much threading stuff. So by nature it exposes more bugs. Now, my rants: > have any other effects on multi-threaded Python code It stops people from using multi-pro…
Note that there is an entire order of magnitude range for a 'single digit'. A 1% slowdown seems totally fine. A 9% slowdown is pretty bad.
Re: The first year of free-threaded Python
#289Earlier quoted context omitted.
It's a matter of perspective, I guess... When you look from the program's perspective, the context changes and becomes unrecognizable, IOW, it rots. When you look from the context's perspective, the program changes by not evolving and keeping up with the context, IOW, it rots. Maybe we anthropomorphize both and say "they grow apart". :)
We say the context has breaking changes. We say the context is not backwards compatible.
Re: The first year of free-threaded Python
#290Earlier quoted context omitted.
Processes can die independently so the state of a concurrent shared memory data structure when a process dies while modifying this under a lock can be difficult to manage. Postgres which uses shared memory data structures can sometimes need to kill all its backend processes because it cannot fully recover from such a state. In contrast, no one thinks about what happens if a thread dies independently because the failu…
> In contrast, no one thinks about what happens if a thread dies independently because the failure mode is joint. In Rust if a thread holding a mutex dies the mutex becomes poisoned, and trying to acquire it leads to an error that has to be handled. As a consequence every rust developer that touches a mutex has to think about that failure mode. Even if in 95% of cases the best answer is "let's exit when that happens"…