以下是我的代码,我建立一个模块qmod,里面有个全局变量eginedata,是多线程共用的。其中的方法run_with_params是打算多线程运行,并把线程内创建的user_data存到全局变量enginedata中,按理说如果存成功了,下面运行pop!(enginedata,params)肯定能正常运行。
# code
module qmod
mutable struct userparam
strategy_name::String
params::String
end
global enginedata = Dict{String,userparam}()
function run_with_params(strategy_name::String, params::String, external_data)
global enginedata
user_data = userparam(strategy_name, params)
enginedata[params] = user_data
pop!(enginedata,params)
return nothing
end
export run_with_params
end
我写了另外一个模块,用来实现多线程调用。
# code
module st01
qmod_path = "D:/strategy/julia/"
if qmod_path in LOAD_PATH
else
push!(LOAD_PATH, qmod_path)
end
using qmod
function config_generator(;continues::Dict{String,<:Vector}=Dict{String, Vector{Number}}(),
discrete::Dict{String, <:Vector}=Dict{String, Vector{Number}}())
allparam = Dict{String, Vector{Number}}()
for paramname in keys(continues)
down, up, cen, width = continues[paramname]
datavector = collect(cen:width:up)
popfirst!(datavector)
push!(datavector, collect(cen:-width:down)...)
allparam[paramname] = copy(datavector)
end
for paramname in keys(discrete)
datavector = discrete[paramname]
allparam[paramname] = copy(datavector)
end
paramname = Tuple(keys(allparam))
parvect = [allparam[key] for key in paramname]
pargrid = vec(collect(Iterators.product(parvect...)))
configset = Vector{Dict{String,Number}}()
for point in pargrid
configi = Dict{String,Number}()
for i in eachindex(paramname)
configi[paramname[i]] = point[i]
end
push!(configset, copy(configi))
end
return configset
end
function do_work()
continues = Dict("delta"=>[1,20,10,1],"short"=>[1,30,10,1],"period"=>[1,60,5,1])
configset = config_generator(continues=continues)
strategy_name = "SMA"
Threads.@threads for params in configset
# for params in configset
long = params["short"] + params["delta"]
short = params["short"]
period = params["period"]
params_str = string(short,"_",long,"_",period)
external_data = Vector{Int}()
run_with_params(strategy_name, params_str, external_data)
end
println(myid(), " th job has done.")
end
end
然后在Julia中按如下方式运行:
然后对于有的params就会报这个错误:
以上代码如果不用Threads.@threads来多线程运行,那不会报错。现在问题就很奇怪,难道线程内对enginedata的赋值不会及时生效?
如果不会立马生效,那应该无论什么params都会报错才对。现在只是某些进程的某些params报错。