If I’m manipulating tasks with yieldto, without the scheduler, when a task finishes it just hangs the REPL (i.e. yieldto(@task 1+1) hangs). So I have to yieldto back to the main task at the end (or is there some other way, without using the scheduler?)
julia> main = current_task();
julia> t = Task() do
x = 1 + 1
yieldto(main, x)
end
Task (runnable) @0x000000012c776380
julia> yieldto(t)
2
but then the task is still “runnable”, it will hang if it’s yielded to again, and its stack is still allocated (at least, until it’s GC’ed). Is there any way to finish the task? I can manually do t._state = 1, to make it done, then if yielded to it will merely return nothing instead of hanging. Is that how it should be done?
The issue is that the REPL is waiting for a task that hasn’t started yet. @task creates a task but doesn’t run it (you can check with istaskstarted(t)). Running schedule(t) tells the scheduler to start the task. I think you have the right idea. I assumed the task wasn’t getting started, until I tried the following:
t=Task() do
println(istaskstarted(t))
end
# yieldto(t) # prints true and hangs
schedule(t) # prints true and ends
yieldto is a low-level command, as opposed to schedule, so you might need to manually schedule tasks and set states when using it. The docs seem to discourage its use for those reasons.
What sort of problem are you solving? Do your tasks need to share data or communicate with each other?
What sort of problem are you solving? Do your tasks need to share data or communicate with each other?
Yeah, my problem isn’t “task is waiting on IO so let’s use that time productively”, but rather “coroutines/continuations are cool for decoupling program logic in an AI context”. I don’t think the scheduler is the right tool. yieldto is nice, but it feels like the low-level layer is missing a handful of primitives. Indeed, looking at the scheduler code, it is not “implemented in terms of yieldto”, as one might hope, but rather full of C calls.
Sending values back and forth is a big part of my use case. I know that I could work around that in various ways (eg. closing over a Ref, or using Conditions), but at that point, straight yieldto looks equally appealing.