目标: 有可能重新加载整个模块并在任务中使用其导出的函数和类型而无需重新启动它们。
问题: 在使用这些函数的任务正在运行时,我遇到了应用新函数定义的问题。我的想法是重新加载一个模块,而不是再次包含一个文件,但在帖子中我还会显示简化的问题版本。
简化示例:
让我用一个只定义一个函数#sample_file.jl
f() = info("f version 01")
的文件来解释这个问题,如下所示:
f
从任务开始每10秒运行一次julia> include("sample_file.jl")
julia> function call_f()
while (true)
f()
sleep(10)
end
end
julia> task = @async call_f()
:
julia> INFO: f version v01
INFO: f version 01
INFO: f version 01
INFO: f version 01
然后我们每10秒钟在一次REPL中看到:
sample_file.jl
现在尝试更改#sample_file.jl
f() = info("f version 02")
中的定义,例如
julia> reload("sample_file")
julia> f()
INFO: f version 02
在REPL中:
julia> INFO: f version 01
INFO: f version 01
INFO: f version 01
INFO: f version 01
INFO: f version 01
...
......但是任务中的信息仍然给出了:
group by
问题:
你有什么想法来解决这个问题吗?
答案 0 :(得分:2)
在您的简化示例中,这是https://github.com/JuliaLang/julia/issues/265。函数call_f
使用f
的原始定义进行编译,并且在f
更改时,当前不会重新编译。
一般来说,我认为您需要考虑在f
发生变化时您想要发生什么。您想要重新编译call_f
吗?不需要重新编译call_f
的简单解决方案是将当前函数f
存储在非const变量中(f
在定义函数时变为const) 。然后jit编译器将知道该函数可以更改并将生成间接调用。
答案 1 :(得分:0)
你所描述的问题的核心是并行计算中的share data,这总是让人坐下来思考可用选项,限制等的理由。
你可以只调用@everywhere
,它会在所有进程上运行命令,但我说这是一个坏主意,因为你可能碰到另一个数据共享/同步问题。
考虑到简短的描述,我最好的选择是使用"获取有关全球状态的更新"的方法:
# main process
# ...
#
if should_update
current_state.updateSomeParameter(newValue)
end
# state is always `spawn`ed
@spawn current_state
# continue doing main process stuff
# on remote process
while do_stuff
# do stuff
fetch(current_state)
updateSelfTo(current_state)
#continue doing my remote stuff
end