Non Blocking Channel Operations in Julia
Basic sends and receives on channels are blocking. However, we can use select with an else clause to implement non-blocking sends, receives, and even non-blocking multi-way selects.
using Printf
function main()
messages = Channel{String}(0)
signals = Channel{Bool}(0)
# Here's a non-blocking receive. If a value is
# available on `messages` then `select` will take
# the `messages` case with that value. If not
# it will immediately take the `else` case.
@select begin
msg = take!(messages) => @printf("received message %s\n", msg)
else => println("no message received")
end
# A non-blocking send works similarly. Here `msg`
# cannot be sent to the `messages` channel, because
# the channel has no buffer and there is no receiver.
# Therefore the `else` case is selected.
msg = "hi"
@select begin
put!(messages, msg) => @printf("sent message %s\n", msg)
else => println("no message sent")
end
# We can use multiple cases above the `else`
# clause to implement a multi-way non-blocking
# select. Here we attempt non-blocking receives
# on both `messages` and `signals`.
@select begin
msg = take!(messages) => @printf("received message %s\n", msg)
sig = take!(signals) => @printf("received signal %s\n", sig)
else => println("no activity")
end
end
main()When you run this program, it will output:
no message received
no message sent
no activityIn Julia, we use the Channel type to create channels. The @select macro is used to implement non-blocking operations on channels, similar to Go’s select statement. The else clause in Julia’s @select serves the same purpose as Go’s default case.
The take! function is used to receive from a channel, while put! is used to send to a channel. These operations are wrapped in the @select macro to make them non-blocking.
Note that Julia’s channel operations are generally blocking by default, but the @select macro allows us to implement non-blocking behavior, similar to Go’s select statement with a default case.