3 ms·
> race conditions everywhere. Async doesn't have this What does Async (Fibers underneath) do differently than normal Threads? Using threads to handle concurren
by Toutouxc 5y ago
> race conditions everywhere. Async doesn't have this
What does Async (Fibers underneath) do differently than normal Threads? Using threads to handle concurrent work doesn't immediately bring race conditions, unless the programmer explicitly creates them (accessing the same stuff from different threads).
Fibers themselves AFAIK don't stop you from accessing the same stuff, aside from the obvious "the fiber code runs 'atomically' until it hits the next yield (which non-blocking Fibers take away anyway).
- BiteCode_dev 5y agoI assumee unless you have a GIL, most operations on collections are not thread safe, but they are async safe, since context switching can only happen where you await.
- gpderetta 5y agoThat's true for stackless coroutines where you can only yield from the top, but I understand that ruby has full coroutines/fibers
- brunosutic 5y ago> What does Async (Fibers underneath) do differently than normal Threads? There's a lot to say on this topic. - Threads implement "preemptive scheduling". A scheduler switches control from one thread to another every 10ms or so. A thread running the code may be ready for the switch or not. The ensuing race conditions are nasty. - Async + Fibers implement "cooperative scheduling". The currently running fiber (voluntarily) yields control to another fiber when it's ready. The result is there are no race conditions. There's so much to say about this, I'll blog about this in the future.
- pqdbr 5y agoI have the same question as parent and I'd love to read more about this distinction. Please do blog about it.
- Matthias247 5y agoIs the scheduler only using a single OS thread? It's not M:N scheduling?
- gpderetta 5y agoCooperative scheduling means that every function call is potentially a scheduling point, so it isn't really a significant change from threads. Sure, if you are careful and only call functions that are not guaranteed to preempt then you are safe, but critical sections make this explicit. And if you are running code on multiple cores then lack of preemption doesn't help anyway.
- dwaite 5y ago> The currently running fiber (voluntarily) yields control to another fiber when it's ready. The result is there are no race conditions. This is generally untrue, as it assumes the developer knows the ramification of which methods hit scheduling points and understand what state the global set of potentially pending work might modify while suspended. You might not have to focus so much about concurrent threads modifying the same memory simultaneously, but you absolutely could have the value change unpredictably during a write-sleep-read. Note there are environments which try to make it more obvious which methods might result in a suspension, and have the developer acknowledge that so that the code remains understandable/maintainable. The keywords used for this are typically 'async' and 'await'.
- jakear 5y agoYep… this is why the “thank goodness these functions aren’t colored!” people confuse me. Colored functions are a very good thing, they make it explicit where context switches happen and make understanding async interactions easy. People who don’t like “colored functions” IMO are similar to folks who don’t like types. They want to be able to change something to be async without a compiler yelling at them to go through all of its call stacks and ensure they can handle the asynchrosity, similar to changing a function to return “null” sometimes and not wanting a compiler to make them verify all calling code can handle a null. That being said, I do wish all functions could be colored. The most painful async migrations are when calling code happens in a constructor, which in JS cannot be made async.
- dwaite 5y agoThere’s value in being able to write code without the ceremony of types or declarations or compulsory exception declarations and the like, just like there’s value in having tools like a REPL. The problem comes in that it takes a lot of discipline and understanding of both your code and dependencies to successfully manage projects without those safety rails. They are also extraordinarily difficult to add-on later. I’ve written small reverse proxies in say Node.js which saved me days of time over doing so in something like Rust. I’ve also hit errors in Node.js code which have made me want to give up on technology and live in a cave.