4 ms·
Thank you for the clarification. You are right, these types of race conditions are possible with Async Ruby. I find these races relatively easy to spot: yes, g
by brunosutic 5y ago
Thank you for the clarification. You are right, these types of race conditions are possible with Async Ruby.
I find these races relatively easy to spot: yes, global state CAN change when you yield back to the reactor.
IMO thread race conditions are much, much worse. Global state can change AT ANY POINT, because thread scheduler preemptively switches threads. Here's an example:
global.a = 0
thread {
global.a = 1
print(global.a) // a is 1 or 2
}
thread {
global.a = 2
print(global.a) // a is 1 or 2
}
print(global.a) // a is 0, 1 or 2
- Yoric 5y ago> I find these races relatively easy to spot: yes, global state CAN change when you yield back to the reactor. It's good that you can find them easily. In my experience, these changes can creep into your code stealthily and only hit you from behind, months later, when the winds shift. Some of my traumas include: - global state that ends up captured by a closure while you didn't realize it was (perhaps because the code you wrote and the code the other dev wrote accidentally shared state); - mutating hashtables/dictionaries while walking them, without anything in your code looking suspicious; - and of course accidentally mixing concurrency between two reactors, but luckily, that's not something that happens every day. > IMO thread race conditions are much, much worse. IMO, thread race conditions are a case of "it's bad but you knew what you'd get when you signed up for it", while async race conditions are a case of "don't worry, everything is going to be fine (terms and conditions apply, please contact your lawyer if you need clarifications)".
- deleted 5y ago[deleted]
- bitwalker 5y agoThis isn't really an issue with threads though, the exact same issue is present in green thread/fiber implementations; it just so happens that in Async Ruby the GIL saves you from this specific problem due to making variable accesses atomic (as I understand it anyway, I'm not super familiar with the Ruby VM). In general, green threads/fibers are vulnerable to the exact same shared memory issues as threads, the only benefit to them is that they are, for a certain class of problems, a more efficient concurrency primitive than threads by avoiding context switches out of userspace, and in many cases provide you the ability to plug in your own scheduler if you so desire allowing you to optimize scheduling for your own workload.
- brunosutic 5y agoThank you for sharing your perspective in a non-conflicting way Yoric. It seems you have more experience than me with async-related work. I'll keep an eye on this kind of scenario you brought up.