EDIT: there is a dockerfile in there https://raw.githubusercontent.com/colesbury/nogil/nogil/Dock...
A viable solution for Python concurrency
91–100 of 366 posts
Re: A viable solution for Python concurrency
#92> 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…
This seems like it would be less efficient if most objects don't escape their owning thread (you would need one atomic inc/dec versus zero), which is probably true of most objects.
Re: A viable solution for Python concurrency
#93> Whenever the owning thread drops a reference to an object, it checks both reference counts against zero. If both the local and the shared count are zero, the object can be freed, since no other references exist. If the local count is zero but the shared count is not, a special bit is set to indicate that the owning thread has dropped the object; any subsequent decrements of the shared count will then free the object if that count goes to zero.
So in this program:
import threading
def produce():
global global_foo
local_foo = "potato"
global_foo = local_foo
def consume():
global global_foo
local_foo = global_foo
global_foo = None
if __name__ == '__main__':
produce()
thread = threading.Thread(target=consume)
thread.start()
thread.join()
What happens to the counts on the string "potato"?In produce, the main thread creates it and puts it in a local, and increments the local count. It assigns it to a global, and increments the local count. It then drops the local when produce returns, and decrements the local count. In consume, the second thread copies the global to a local, and increments the shared count. It clears out the global, and decrements the shared count. It then drops the local when consume returns, and decrements the shared count.
That leaves the local count at 1 and the shared count at -1!
You might think that there must be special handling around globals, but that doesn't fix it. Wrap the string in a perfectly ordinary list, and put the list in the global, and you have the same problem.
I imagine this is explained in the paper by Choi et al, but i have not read it!
Re: A viable solution for Python concurrency
#94Earlier quoted context omitted.
Most objects are never shared so there would be a performance impact from incrementing (and decrementing) an atomic counter even just once.
That is true, but what if the shared count were initialized to one and the creator thread frees an object when the shared count is equal to one and the local count is decremented zero? (Since it knows it holds one shared reference.) Then the increment and decrement would be avoided for non-shared objects.
Re: A viable solution for Python concurrency
#95If 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.
If you are ever considering making use of asyncio for your project, I would strongly recommend taking a look at curio [1] as an alternative. It's like asyncio but far, far easier to use. [1] https://curio.readthedocs.io/en/latest/index.html
But yes, consider alternatives before you pick asyncio as your approach!
Talk: https://www.youtube.com/watch?v=oLkfnc_UMcE
Blog post: https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
Re: A viable solution for Python concurrency
#96If 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.
If you are ever considering making use of asyncio for your project, I would strongly recommend taking a look at curio [1] as an alternative. It's like asyncio but far, far easier to use. [1] https://curio.readthedocs.io/en/latest/index.html
Re: A viable solution for Python concurrency
#97If 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.
Minus the "natively supported" part, we have this today in http://www.gevent.org/ ! It's so, so empowering to be able to access the entire historical body of work of synchronous-I/O Python libraries, and with a single monkey patch cause every I/O operation, no matter how deep in the stack, to yield to your greenlet pool without code changes.
We fire up one process per core (gevent doesn't have good support for multiprocessing, but if you're relying on that, you're stuck on one machine anyways), spend perhaps 1 person-day a quarter dealing with its quirks, and in turn we never need to worry about the latencies of external services; our web servers and batch workers have throughput limited only by CPU and RAM, for which there's relatively little (though nonzero) overhead.
IMO Python should have leaned into official adoption of gevent. It may not beat asyncio in raw performance numbers because asyncio can rely on custom-built bytecode instructions, whereas gevent has "userspace" code that must execute upon every yield. And, as with asyncio, you have to be careful about CPU-intensive code that may prevent you from yielding. But it's perfect for most horizontal-scaling soft-realtime web-style use cases.
Re: A viable solution for Python concurrency
#98If 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.
If you are ever considering making use of asyncio for your project, I would strongly recommend taking a look at curio [1] as an alternative. It's like asyncio but far, far easier to use. [1] https://curio.readthedocs.io/en/latest/index.html
Re: A viable solution for Python concurrency
#99If 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.
If you are ever considering making use of asyncio for your project, I would strongly recommend taking a look at curio [1] as an alternative. It's like asyncio but far, far easier to use. [1] https://curio.readthedocs.io/en/latest/index.html
And since we are stuck with colored functions in python, the choice of stack matters very much.
Now, if you want easier concurrency, and a solution to a lot of concurrency problems that curio solves, while still being compatible with asyncio, use anyio:
https://anyio.readthedocs.io/en/stable/
It's a layer that works on top of asyncio, so it's compatible with all of it. But it features the nursery concept from Trio, which makes async programming so much simpler and safer.
Re: A viable solution for Python concurrency
#100If 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.
If you are ever considering making use of asyncio for your project, I would strongly recommend taking a look at curio [1] as an alternative. It's like asyncio but far, far easier to use. [1] https://curio.readthedocs.io/en/latest/index.html
I have used Trio in real projects and I thoroughly recommend it.
This blog post [2] by the creator of Trio explains some of the benefits of those libraries in a very readable way.
[1] https://trio.readthedocs.io/en/stable/
[2] https://vorpus.org/blog/some-thoughts-on-asynchronous-api-de...