@spawn and @async in producer-consumer problem


I am trying to implement a producer-consumer problem, where I want one thread to produce some data and a second thread to take the data and write them to a disk. I am using Channel as my queue so that the producer will put! the data to the channel and the consumer will take them. I can run the consumer on the main thread, but I am not sure how I should create the producer thread. I do not understand the difference between Threads.@spawn and Threads.@async.

As far as I can tell, the “only” (but potentially important) difference is, that @async sets the sticky bit on the created task, whereas @spawn does not (or rather, removes it, because it is set by default on newly created tasks). The sticky bit signals that a task is to be executed on the thread that schedules it only. A non-sticky task can be freely scheduled and moved around available threads.

Chances are you want @spawn.

use @macroexpand to see what each of @async, @spawn does.

And with the task moving around between threads comes the whole class of thread-safety problems. So for things where you don’t want to worry about thread-safety, but just want IO to happen without blocking, @async is a good default.

There should be no problem with thread-safety. The only data that the consumer will access are the final data from the producer. The communication between these two is handled with Channel, so thread-safety should be guaranteed.

1 Like

use @macroexpand to see what each of @async, @spawn does.

How can I do that? When I try to execute @macroexpand Threads.@async I got an error because REPL is trying to execute the @async macro.

Ok, I figured it out, I just need to do something like @macroexpand Threads.@async (x) -> x, for example.