Reputation: 123
This is my idea
task=@task begin
while true
sleep(1)
foo()
if should_end
# ?
end
end
end
But there are some problems
global should_end
?Upvotes: 0
Views: 132
Reputation: 2162
While implementing something like this can be a good exercise, note that Timers are in the standard library and they are similar to the JS functions you may be used to because Julia and Node.js both use libuv internally. Whether you use Node.js setInterval
or Timeout
, or Julia Timer
eventually uv_timer_start
is called (although the creation and low-level management of timers is different in the respective runtimes).
To answer your 2nd question, you can just break
in the if
expression:
julia> should_end = false
false
julia> task = @task begin
while true
sleep(1)
if should_end
break
end
end
"Tasks can return a value"
end
Task (runnable) @0x00007fca1c9c3990
julia> schedule(task)
Task (runnable) @0x00007fca1c9c3990
julia> task
Task (runnable) @0x00007fca1c9c3990
julia> should_end = true;sleep(1)
julia> task
Task (done) @0x00007fca1c9c3990
julia> fetch(task)
"Tasks can return a value"
As for the 1st question, there is a lot of information in the Julia docs, e.g. the Asynchronous Programming section. As is described there, Channels can be used for communication between tasks (when suitable). Note that should_end
doesn't have to be global
. A task wraps a function and that function can capture variables in enclosing scopes (@task begin a = 1 end
is really just Task(() -> begin a = 1 end)
.
Here is a short example using a Timer
and a Channel
to send data to a task:
function pinger(n)
ping() = parse(Float64, match(r"time=(.*) ms", read(`ping -c 1 8.8.8.8`, String))[1])
ch = Channel{Float64}(0)
pinger = Timer(0.0; interval=1.0) do timer
put!(ch, ping())
end
summer = @task begin
total = 0.0
count = 0
while count < n
total += take!(ch)
count += 1
end
total / count
end
schedule(summer)
fetch(summer)
end
julia> pinger(3)
19.5
Upvotes: 1