Hacker News new | ask | show | jobs
by samsquire 1338 days ago
I am really interested in this space.

There's an article that Cal Paterson wrote that async doesn't speed up code - it is not parallel. The GIL prevents Python from being parallel. So even if you create a thread to run an async method in Python, it shall not run in parallel to the main thread of execution. (In fact, it shall block the main thread of execution if you start a thread in the thread you are in, due to the blocking run_in_executor)

https://calpaterson.com/async-python-is-not-faster.html

I wrote a multithreaded userspace 1:M:N scheduler (1 scheduler thread, M kernel threads and N lightweight/green threads) which resembles Golang M:N model. I implemented the same design in Rust, C and Java. I am thinking it could be combined with my epoll-server and it would be an application server.

https://github.com/samsquire/preemptible-thread https://github.com/samsquire/epoll-server

I am also interested in structured concurrency. This article by Vala developers is good.

https://verdagon.dev/blog/seamless-fearless-structured-concu...

I am trying to find a concurrent software design that is scalable and is easy to write and hides complicated lock programming. I document my studies and ideas in the open in ideas4.

https://github.com/samsquire/ideas4

I've implemented multithreaded parallel multiversion concurrency control in Java, which is the same approach used by Postgresql and MySQL for concurrent read and writing to the same data atomically.

I still think concurrency is hard to write and understand. Even with async/await.

// 3 requests in flight

result1 = async_task1();

result2 = async_task2();

result3 = async_task3();

await result1;

await result2;

await result3;

I ported a parallel multiconsumer multiproducer ringbuffer from Alek

https://www.linuxjournal.com/content/lock-free-multi-produce...

I use Python threads in https://github.com/samsquire/devops-schedule and https://github.com/samsquire/parallel-workers to parallelise a topologically sorted graph of IO of devops programs. This allows efficient scheduling and blocking with thread.join() for each split of the work graph and then a regrouping before doing other things, also potentially in parallel. This pattern is efficient and easy to use.

2 comments

> await result1;

> await result2;

> await result3;

Not really, you only have *1* request in flight.

And you're waiting for them sequentially.

You need asyncio.gather ( https://docs.python.org/3/library/asyncio-task.html#asyncio.... ) if you want to run tasks concurrently.

results = await asyncio.gather(result1, result2, result3)

Before the first await result1 the coroutine objects are in flight.
Nope, creating the coroutines doesn’t schedule them for execution. That only happens on await. Python is not eager. If you want that behavior you need to use create_task. It doesn’t work like spawning a thread and waiting on them.

From the docs: https://docs.python.org/3/library/asyncio-task.html

> Note that simply calling a coroutine will not schedule it to be executed:

Oh this is not what I expected.

I think on C# you can await threads which is similar to a join() with a return value.

  // 3 requests in flight

  result1 = async_task1();

  result2 = async_task2();

  result3 = async_task3();
Depends on implementation, some are eager, some are lazy.