As the title suggests, trying to call get! on an empty dictionary in multiple threads concurrently will cause an error to be thrown. Example:
dd = Dict()
Threads.@threads for i in 1:1000
get!(dd, i, 2)
end
The issue I have with this (in julia 1.12) is that I have a parallelized loop in which a function as part of its logic checks whether two values are approximately the same. To check that, it needs tolerance values for the given numeric type, which are stored inside a constant dictionary object in the ReachabilityBase package. However, I haven’t set any tolerance values, meaning that dictionary is empty. The expected behavior there is to use default tolerance values, but instead I get the following error: AssertionError: Multiple concurrent writes to Dict detected!
Apparently the get! function calls the ht_keyindex2_shorthash! function, which in turn rehashes the dictionary if it’s empty. What is the reasoning behind this? I wouldn’t expect a read operation to not be thread-safe.
Usually I would use get, but in my case I depend on a core julia package which uses get!. Maybe a more appropriate question would be why get! even exists?
cache = Dict{String, String}()
value = get!(cache, "key") do
# this function is called only when "key" is missing in cache
return fetch_value("key")
end
Then I suggest you open an issue with that package to ask if they can provide a read-only option for the operation you need.
No, that is not an appropriate question. get! is one of the frequently used operations you need to perform on a dictionary. Yes, you can build it up from other primitives but doing so every time you need get! would be repetitive and a potential source of buggy and less-than optimal implementations.
That is a very good question though. I have a hard time seeing the point.