Live data from Hacker News

A viable solution for Python concurrency

lwn.net

131–140 of 366 posts

Re: A viable solution for Python concurrency

#131
post #19

If this effort succeeds (and I hope it does) now Python developers will need to contend with the event-loop albatross of asyncio and all of its weird complexity. In an alternate Python timeline, asyncio was not introduced into the Python standard library, and instead we got a natively supported, robust, easy-to-use concurrency paradigm built around green/virtual threading that accommodates both IO and CPU bound work.

What specifically is the problem with asyncio? I quite like using it, so I'm curious if there's some aspect that makes it unsustainable?

It solves only one problem, the name says it: Async I/O

If you do anything on the CPU or if you have any I/O which is not async you stall the event loop and everything grinds to a halt.

Imagine a program which needs to send heartbeats or data to a server in a short interval to show liveness, Kafka for example. Asyncio alone can't reliably do this, you need to take great care to not stall the event loop. You only have exactly one CPU core to work with, if you do work on the CPU you stall the event loop.

We see web frameworks built on asyncio but even simple API only applications constantly need to serialize data which is CPU-bound. These frameworks make no effort (and asyncio doesn't give us any tools) to protect the event loop from getting stalled by your code. They work great in simple benchmarks and for a few types of applications but you have to know the limits. And I feel that the general public does not know the limitations of asyncio, it wasn't made for building web frameworks on the async event loop. It was made for communicating with external services like databases and calling APIs.

Re: A viable solution for Python concurrency

#132
post #82
post #43

Earlier quoted context omitted.

No, I mean several threads doing completely separate CPickle streams with no shared data or variables at the Python level.

Has it since been fixed?

Probably not. CPickle is famously shunned by anyone who has to do serious, performance-critical serialization/deserialization.

Re: A viable solution for Python concurrency

#134

> With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast, non-atomic instructions. Any other thread accessing the object will use atomic operations on the shared reference count. > Whenever the owning th…

Suppose thread A (the owner) keeps a reference, but also puts another reference in a global variable. This would increment its local refcount to 1 and have a shared refcount of 1.

Then thread B clears the global variable. With your scheme the local refcount would be 1 but the shared refcount would be 0, so thread B would destroy the object even though it's referenced by thread A.

Re: A viable solution for Python concurrency

#135

> With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast, non-atomic instructions. Any other thread accessing the object will use atomic operations on the shared reference count. > Whenever the owning th…

> which is released (using the same decref code as other threads) when the local reference count goes to zero? (I may misunderstand your remark, as ‘releasing’ is a bit ambiguous. It could mean decreasing reference count and freeing the memory if the count goes to zero or just plain freeing the memory) The local ref count can go to zero while other threads still have references to the object (e.g. when the allocating…

> I may misunderstand your remark, as 'releasing' is a bit ambiguous.

The reference is released; ie the (atomic) reference count is decremented (and the object is only freed if that caused the atomic reference count to go to zero).

> From the paper

I missed that there was a paper and was referring to the proposed implementation in python that was described in TFA. IIUC, biased refcount (in paper) is local (in my description), and shared is atomic, correct?

> the shared ref count can go negative

And that makes sense. Thanks. (And also explains how to deal with references added by one thread and removed by another, when one of those threads is the object owner.)

Re: A viable solution for Python concurrency

#136

Earlier quoted context omitted.

"Viable" as in "you have no other choice sometimes". This forces you to deal with 3 libraries each with their own quirks, pitfalls and incompatibilities. Sometimes you even deal with dependencies reimplementing some parts in a 4th or 5th library to deal with shortcomings. I really don't care that much which of them survive, I just want to rely on less of them

No, it's just useful. They are techs with different trade off, and life is full of opportunities.

Python Zen = one obvious way to do it. Having a bunch of very different ones, each with serious disadvantages, is a bad look.

Re: A viable solution for Python concurrency

#137

> With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast, non-atomic instructions. Any other thread accessing the object will use atomic operations on the shared reference count. > Whenever the owning th…

I think yours is a much cleaner design. In the original plan, if the owning thread just set the special bit, but before that set is propagated, another thread drops the shared refcount to zero, the object would never be released, would it?

EDIT: never mind the question, I just read that the special bit is atomic.

Re: A viable solution for Python concurrency

#138

Earlier quoted context omitted.

No, it's just useful. They are techs with different trade off, and life is full of opportunities.

Python Zen = one obvious way to do it. Having a bunch of very different ones, each with serious disadvantages, is a bad look.

Zen of Python is an ideal, and at this point, kind of tongue-in-cheek.

This is the same language that shipped with at least 3 different methods to apply functions across iterables when the Zen of Python was adopted as a PEP in 2004.

Re: A viable solution for Python concurrency

#139

Earlier quoted context omitted.

No, it's just useful. They are techs with different trade off, and life is full of opportunities.

Python Zen = one obvious way to do it. Having a bunch of very different ones, each with serious disadvantages, is a bad look.

It's a technical thread, not a political one. If you were so sure of your argument, you wouldn't use a throwaway.

Besides, it's weird, like saying we should not have int, float and complex, there should be one way to do it.

Just because those are 3 numbers doesn't mean they don't have each their own specific benefit.

Post reply on HN