Create multiple tasks in a loop

Hi everyone,

I am trying to create multiple tasks in a forr loop using @eval. Here is a block of code

f(k) = begin sleep(1)
     println("t$k is done")
 end

begin
    for k in 1:4
         @eval $(Symbol(:t,k)) = @task f(k)
    end
    sleep(1)
    for k in 1:4
        @eval schedule($(Symbol(:t,k)))
    end
end

I want to assing the value k into the f() function when creating a task However, Julia throws back error

UndefVarError: k not defined

The error is caused by this line

@eval $(Symbol(:t,k)) = @task f(k)

How to correct this?

Any help would be appreciated!

Sitthichat

Is there a particular reason why you’d want to have your tasks in separate t1, t2, … variables instead of putting them in an array and referencing them as t[1], t[2], …?

If it works for you, an array-based solution would IMO be more Julian; it could look like this:

julia> function f(k)
           sleep(1)
           println("task $k is done")
       end
f (generic function with 1 method)

julia> tasks = [@task f(k) for k in 1:4]
4-element Vector{Task}:
 Task (runnable) @0x00007f10aa7b70a0
 Task (runnable) @0x00007f10aa7b71f0
 Task (runnable) @0x00007f10aa7b7340
 Task (runnable) @0x00007f10aa7b7490

julia> sleep(1)

julia> for t in tasks
           schedule(t)
       end

task 1 is done
task 2 is done
task 3 is done
task 4 is done
6 Likes

You could insert $ in front of k so that it should be f($k).
It worked for me.

@eval $(Symbol(:t,k)) = @task f($k)

1 Like

Indeed! This looks more Julian. Thanks so much

1 Like

You can even collapse them into a single instruction:

schedule.(@task f(k) for k=1:4)
or
foreach(schedule, (@task f(k) for k=1:4))

In order to create a task and schedule it immediately (which was not the case in the OP), it is more direct to use @async:

tasks = [@async f(k) for k in 1:n]
1 Like