Threads.@threads for i in [sth]
x = 123
...
end
Является ли поток x
локальным. Я не могу найти ни одного документа об этом.
Если нет, то как я могу получить локальный поток.
Предполагая, что x
является локальным внутри цикла, тогда да. Вот пример, как это можно проверить:
# julia -t 2 --banner=no
julia> Threads.@threads for i in 1:8
x = i
@info Threads.threadid(), i, x
sleep(rand())
@info Threads.threadid(), i, x
end
[ Info: (1, 1, 1)
[ Info: (2, 5, 5)
[ Info: (1, 1, 1)
[ Info: (1, 2, 2)
[ Info: (2, 5, 5)
[ Info: (2, 6, 6)
[ Info: (1, 2, 2)
[ Info: (1, 3, 3)
[ Info: (2, 6, 6)
[ Info: (1, 3, 3)
[ Info: (1, 4, 4)
[ Info: (2, 7, 7)
[ Info: (1, 4, 4)
[ Info: (2, 7, 7)
[ Info: (2, 8, 8)
[ Info: (2, 8, 8)
Для каждого потока все, что передается внутри тела цикла for
, аннотированного Threads.@threads
, оборачивается анонимной функцией. Вы можете проверить это с помощью функции @macroexpand
.
Обратите внимание, что это даже больше x
: получает новую привязку с каждой итерацией цикла (это стандартное поведение Джулии — неважно, однопоточный это или многопоточный код, см. здесь).
Если x
не является локальной переменной внутри цикла for
, это уже не так, как вы можете видеть здесь:
# julia -t 2 --banner=no
julia> function f()
x = 1
Threads.@threads for i in 1:8
x = i
@info Threads.threadid(), i, x
sleep(rand())
@info Threads.threadid(), i, x
end
end
f (generic function with 1 method)
julia> f()
[ Info: (1, 1, 5)
[ Info: (2, 5, 5)
[ Info: (1, 1, 5)
[ Info: (1, 2, 2)
[ Info: (2, 5, 2)
[ Info: (2, 6, 6)
[ Info: (2, 6, 6)
[ Info: (2, 7, 7)
[ Info: (1, 2, 7)
[ Info: (1, 3, 3)
[ Info: (1, 3, 3)
[ Info: (1, 4, 4)
[ Info: (2, 7, 4)
[ Info: (2, 8, 8)
[ Info: (2, 8, 8)
[ Info: (1, 4, 8)