Julia 重新加载模块/文件和任务问题
目标: 可以重新加载整个模块并在任务中使用其导出的函数和类型,而无需重新启动它们 问题: 在使用新函数定义的任务运行时,应用新函数定义有问题。我们的想法是重新加载一个模块,而不是再次包含一个文件,但在本文中我进一步展示了简化的问题版本 一个简化示例: 让我用一个文件只定义一个函数Julia 重新加载模块/文件和任务问题,julia,Julia,目标: 可以重新加载整个模块并在任务中使用其导出的函数和类型,而无需重新启动它们 问题: 在使用新函数定义的任务运行时,应用新函数定义有问题。我们的想法是重新加载一个模块,而不是再次包含一个文件,但在本文中我进一步展示了简化的问题版本 一个简化示例: 让我用一个文件只定义一个函数f,来解释这个问题,如下所示: #sample_file.jl f() = info("f version 01") 从任务开始,每10秒运行一次f: julia> include("sample_file.j
f
,来解释这个问题,如下所示:
#sample_file.jl
f() = info("f version 01")
从任务开始,每10秒运行一次f
:
julia> include("sample_file.jl")
julia> function call_f()
while (true)
f()
sleep(10)
end
end
julia> task = @async call_f()
然后在每10秒的REPL中,我们会看到:
julia> INFO: f version v01
INFO: f version 01
INFO: f version 01
INFO: f version 01
现在尝试更改示例文件.jl
中的定义,例如
#sample_file.jl
f() = info("f version 02")
在答复中:
julia> reload("sample_file")
julia> f()
INFO: f version 02
…但任务中的信息仍然提供:
julia> INFO: f version 01
INFO: f version 01
INFO: f version 01
INFO: f version 01
INFO: f version 01
...
问题:
你有什么想法来解决这个问题吗?你所描述的问题的核心是并行计算,这总是一个坐下来思考可用选项、限制等的理由 您可以只调用在所有进程上运行命令的,但我认为这是一个坏主意,因为您可能会遇到另一个数据共享/同步问题 考虑到简短的描述,我的最佳选择是使用“获取全球状态更新”方法:
# 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
在您的简化示例中,这是。函数
call\u f
使用f
的原始定义进行编译,当前在f
更改时不会重新编译
一般来说,我认为当代码< f>代码>改变时,你需要考虑你想发生什么。是否要重新编译
call\u f
?不需要重新编译call\u f
的简单解决方案是将当前函数f
存储在非常量变量中(f
在定义函数时变为常量)。然后jit编译器将知道函数可以更改,并将生成一个间接调用 谢谢你的关注和时间。问题与协程(单个线程中的多任务处理)有关,而与不同的线程/进程无关。即使如此,您仍然需要在不同的进程/线程/执行器之间共享全局状态,这从来没有这么简单。在您的特定情况下,您可以通过spawn
ing和fetch
ing使协同程序/任务/线程知道.jl文件上的更改。再说一遍,更改.jl文件可能不是共享数据/状态的最佳方式是的,我是通过共享状态对象来实现的。至于你的建议,我不太确定共享对象是否应该包含所有已更改的函数和类型。首先,我想知道为什么任务对任何重新加载都没有反应(无论是从外部还是从内部)。有什么想法吗?对一个变量的赋值适用于简化的例子。现在,我将尝试在模块版本中使用它。不幸的是,同样的方法在模块中不起作用模块文件=#模块sample2#模块导出f()=info(“f版本v001”)结束#=主代码=#使用sample2#模块函数调用(U f()vf=sample2#模块。f#vf=f也不起作用!(true)vf()sleep(10)end end task=@async call_f()#=end of code=#您对模块和您指出的问题有什么经验吗?