Dicts in different @async blocks

It’s this safe? Using Dict async in the same thread?

d = Dict()

@async do_something_with_d(d)

@async do_something_else_with_d(d)

Maybe something can go wrong when you have I/O in hash or isequal of custom key type? It’s not nice to make them inpure but it’s conceivable for someone to put @debug statements in these functions.

1 Like

I don’t know for sure but probably not. You may want to use a Lock to synchronize access.

P.S. Last I asked about how to determine whether something is thread safe. The answer is to test it out vigorously and see if it crashes. It would be good if the documentation spells out clearly.

2 Likes

The question was if Dict is safe to use concurrent (but not parallel) tasks started via @async. Dict is obviously not “thread-safe” ("@spawn/@threads-safe").

Though I agree that it’s a good idea to use a lock in this case anyway if you really need simultaneous access to Dict. (Even better and often much more efficient approach is to restructure your program so that you don’t need to use raw lock or atomics.)

No offense, but I believe this is a very dangerous attitude towards thread programming. In principle, you should be able to prove that that your program does not have data race given the public API definitions of the functions you are using. The behavior of your program is undefined otherwise. But I agree that documentation is lacking. Even basic thread programming constructs like Channel do not explicitly mention what operations are thread-safe in the docstring.

4 Likes

Is there a lot of overhead associated with locks?

Which kind of lock should I use?
(I know: it depends. One concurrent task has to access a couple of 1000 times per second and the other task every so often)

I think Julia only has ReentrantLock and Threads.SpinLock ATM. You can look at Threads.SpinLock docstring for its caveats. But I think ReentrantLock is the first goto solution anyway. Or are you talking about implementing locks yourself?

1 Like

@tkf I am in 100% agreement with you. Documentation makes a difference. Or the API should be clear e.g. thread-safe data structures could carry a prefix like TS (abbreviation of thread-safe for lack for a better suggestion) so it’s easy to determine if it’s the right data structure to use for writing thread-safe programs.

2 Likes

No I don’t want to implement lock by myself. I tried Semaphore because this way awaiting tasks are waiting in a queue and will be notified in a FIFO manner.

If semaphore works for your case then I suppose that’s good? Though semaphore (at least Julia’s) doesn’t have the FIFO semantics. You can use channel if you want FIFO.