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 select
s.
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 activity
In 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.