-
Notifications
You must be signed in to change notification settings - Fork 420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrent::Hash and Concurrent::Array are not fully threadsafe on CRuby #929
Comments
Hmmm I can see the misunderstanding. The docs say "ensuring only one thread can be reading or writing at a time" and that's what's going on here - one thread reads at a time, and one thread writes at a time, but not both in a single atomic action. The behaviour you're expecting is implemented on the other VMs, but that's really because they over-compensate and lock everything, which also isn't very healthy. I'd welcome discussion. |
The docs say: "A thread-safe subclass of Hash/Array". I guess the question is: what is meant by thread safe? I tried googling and wasn't able to find a crystal clear definition. One level of "thread safety" is that the object remains internally consistent while being used concurrently. As an example where this is not the case one can try manipulating a regular Ruby array from multiple threads using JRuby. CRubys A stronger form of thread safety is when "all methods contain sufficient internal synchronization that instances may be used concurrently without the need for external synchronization"1. Wikipedia2 states that thread safe means that the "Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously". I hope we can agree that the I think the part about "need for external synchronization" in the above quote is particularly interesting. As of now there's no way to use |
If you want these methods to be atomic right now as a workaround, a solution is to use compare-and-swap via |
This is more than I expect from 'thread safe' also and I think the CRuby behavior is fine. The problem I see is that the library is inconsistent. On both JRuby and TruffleRuby the thread execution is serialized and the block is atomic. I think having a synchronised |
I don't have an application depending on this. I was simply trying things and was surprised by the behaviour. It just seems like something that could catch people by surprise if they're unaware of it. I don't see how I could make an implementation using |
I see it now :) |
Fixing this would mean adding overhead for Concurrent::Array on CRuby. Currently only that first level of #929 (comment) thread-safety is guaranteed. I.e., internal consistency, but it does not make Ruby blocks or operations accessing multiple indices atomic. Only individual read and writes are atomic. |
If I understand this issue correctly (and I think that I do), I want to point out that the documentation on Array explicitly states that iteration operations like And, for the record, I appear to be running into this issue in my professional development. |
@eviljoel Right, this is indeed inconsistent. The documentation is the intended behavior but is indeed not the case on CRuby. I plan to fix this issue and so make it match the intended behavior. |
Concurrent::Hash
andConcurrent::Array
are not fully threadsafe on CRuby.This can be demonstrated for
Array
with:This returns
[1]
.For
Hash
this code shows the issue:This returns
{a: 1}
.In both cases we would expect to see 20 instead of 1.
The text was updated successfully, but these errors were encountered: