Live data from Hacker News

Show HN: Bringing multithreading to Python's async event loop

github.com

21–30 of 47 posts

Re: Show HN: Bringing multithreading to Python's async event loop

#21

I am fairly confident I will get some down votes for this, but here goes... When I am trying to solve a technical problem, the problem is going to dictate my choice of tooling. If I am doing some fast scripting or I need to write some glue code, python is my go-to. But if I have a need for resource efficiency, multi threading, non-blocking async i/o, and/or hi performance, I would not consider python - I would probab…

Sure, this works sometimes. But sometimes you have mountains of code and infrastructure dedicated to one platform, and it's worth the effort to round off the occasional square peg in the interest of operational simplicity/consistency.

I've been using ThreadPoolExecutors in Python for a while now. They seem to work pretty well for my use cases. Granted, my use cases don't require things like shared memory segments; I use as_* functions under concurrent.futures to recombine the data as needed. Honestly, I prefer the futures functions as I don't need to think about deadlocks.

Re: Show HN: Bringing multithreading to Python's async event loop

#22
post #13

Perhaps a silly question, but should an event loop actually be multithreaded? My understanding was that tasks in an event loop should yield after they dispatch IO tasks, which means the event loop should be CPU-bound right? If so, multithreading should not help much in theory?

This was exactly my question. Why do you even need an event loop? If awaits are just thread joins then what is the event loop actually doing? IO can just block, since other coroutines are on other threads and are unaffected. Which is to say, why even bother with async if you want your code to be fully threaded? Async is an abstraction designed specifically to address the case where you're dealing with blocking IO on…

Looking at the article he's not implementing `Task` with `Thread` - he's round-robinning processing `Task`s through simple `ThreadPool`. So instead of a single `Thread` making continuous progress on the work in the event loop he instead has a set of `Thread`s making progress _in parallel_ on work in the event loop. This is very much Java 21's approach to virtual threads (as well as in-language task runners like the kind you find in Scala libraries like ZIO, Monix, Cats, and the venerable Scalaz).

Re: Show HN: Bringing multithreading to Python's async event loop

#23
post #22

Earlier quoted context omitted.

This was exactly my question. Why do you even need an event loop? If awaits are just thread joins then what is the event loop actually doing? IO can just block, since other coroutines are on other threads and are unaffected. Which is to say, why even bother with async if you want your code to be fully threaded? Async is an abstraction designed specifically to address the case where you're dealing with blocking IO on…

Looking at the article he's not implementing `Task` with `Thread` - he's round-robinning processing `Task`s through simple `ThreadPool`. So instead of a single `Thread` making continuous progress on the work in the event loop he instead has a set of `Thread`s making progress _in parallel_ on work in the event loop. This is very much Java 21's approach to virtual threads (as well as in-language task runners like the k…

How is that materially different than just making async invocations thread forks and awaits into joins? I understand what the code is doing, I just don't understand what the point is, when it seems like the net effect is the same as just writing threaded code.

Re: Show HN: Bringing multithreading to Python's async event loop

#24

I am fairly confident I will get some down votes for this, but here goes... When I am trying to solve a technical problem, the problem is going to dictate my choice of tooling. If I am doing some fast scripting or I need to write some glue code, python is my go-to. But if I have a need for resource efficiency, multi threading, non-blocking async i/o, and/or hi performance, I would not consider python - I would probab…

The main object is the in-between-land, where you need 10x-50x the performance of Python, not 500x the performance on some parallelizable workload. And in many teams, just having to worry about python makes it easier to keep team members productive if they're not expected to handle several different languages productively.

Fair point. Tho I will push back on...

> And in many teams, just having to worry about python makes it easier to keep team members productive if they're not expected to handle several different languages productively.

I think this makes sense for individuals and teams, but for an org or company I think having specialist teams makes sense where teams that require perf use JVM and teams that make business-ware or devops or something not perf would use python.

Re: Show HN: Bringing multithreading to Python's async event loop

#25

I am fairly confident I will get some down votes for this, but here goes... When I am trying to solve a technical problem, the problem is going to dictate my choice of tooling. If I am doing some fast scripting or I need to write some glue code, python is my go-to. But if I have a need for resource efficiency, multi threading, non-blocking async i/o, and/or hi performance, I would not consider python - I would probab…

Sure, this works sometimes. But sometimes you have mountains of code and infrastructure dedicated to one platform, and it's worth the effort to round off the occasional square peg in the interest of operational simplicity/consistency. I've been using ThreadPoolExecutors in Python for a while now. They seem to work pretty well for my use cases. Granted, my use cases don't require things like shared memory segments; I…

> Sure, this works sometimes. But sometimes you have mountains of code and infrastructure dedicated to one platform, and it's worth the effort to round off the occasional square peg in the interest of operational simplicity/consistency.

I agree with this, this is a fair trade off, but not the direction I would go as a matter of preference.

Re: Show HN: Bringing multithreading to Python's async event loop

#26

I am fairly confident I will get some down votes for this, but here goes... When I am trying to solve a technical problem, the problem is going to dictate my choice of tooling. If I am doing some fast scripting or I need to write some glue code, python is my go-to. But if I have a need for resource efficiency, multi threading, non-blocking async i/o, and/or hi performance, I would not consider python - I would probab…

Surely your comment only really makes sense from the point of view of green field or hobbyist projects? If you were working for an organization with hundreds of thousands of lines of Python already doing something important, then your last sentence doesn't hold, right?

Re: Show HN: Bringing multithreading to Python's async event loop

#27

I am fairly confident I will get some down votes for this, but here goes... When I am trying to solve a technical problem, the problem is going to dictate my choice of tooling. If I am doing some fast scripting or I need to write some glue code, python is my go-to. But if I have a need for resource efficiency, multi threading, non-blocking async i/o, and/or hi performance, I would not consider python - I would probab…

The problem is that your example is not most of the companies that uses python are facing, which is the majority of the python code. They want some kind of performance uplift without rewriting the whole python code base. It's cheaper if python keeps getting some kind of upgrade

An example is facebook's php to hack compiler

Re: Show HN: Bringing multithreading to Python's async event loop

#28
post #7
post #3

> It got me wondering if it was actually possible to make Python’s async event loop work with multiple threads. There is built-in support for this. Take a look at loop.run_in_executor. You can await something scheduled in a separate Thread/ProcessPoolExecutor. Granted, this is different than making the async library end-to-end multi-threaded as you seem to be trying to do, but it does seem worth mentioning in this co…

run_in_executor is pretty powerful for running sync code in async code, but my use case was more making async code utlize the cpu better. I think, just using run_in_executor would add a lot of complication and changes to how you use async await. But great point none the less!

> but my use case was more making async code utlize the cpu better

But run_in_executor achieves that as well! If you use no-GIL Python and a thread pool (or GIL Python with a Process pool), you will utilize more CPU cores.

Re: Show HN: Bringing multithreading to Python's async event loop

#29
post #11
post #7

Earlier quoted context omitted.

run_in_executor is pretty powerful for running sync code in async code, but my use case was more making async code utlize the cpu better. I think, just using run_in_executor would add a lot of complication and changes to how you use async await. But great point none the less!

I've had plenty of success using run_in_executor in production. You basically just use the decorator, and it mostly just works.

Which decorator?

Re: Show HN: Bringing multithreading to Python's async event loop

#30
post #22

Earlier quoted context omitted.

Looking at the article he's not implementing `Task` with `Thread` - he's round-robinning processing `Task`s through simple `ThreadPool`. So instead of a single `Thread` making continuous progress on the work in the event loop he instead has a set of `Thread`s making progress _in parallel_ on work in the event loop. This is very much Java 21's approach to virtual threads (as well as in-language task runners like the k…

How is that materially different than just making async invocations thread forks and awaits into joins? I understand what the code is doing, I just don't understand what the point is, when it seems like the net effect is the same as just writing threaded code.

If I understand correctly, it sounds like the idea is to map N tasks to M threads.

I suppose it’d only really be useful if you have more tasks than you can have OS threads (due to the memory overhead of an OS thread), then maybe 10,000 tasks can run in 16 OS threads.

If that’s the case, then is this useful in any application other than when you have way too many threads to feasibly make each task an OS thread?

Post reply on HN