首页 > 解决方案 > 从 crontab 调度程序 (Linux) 运行时,Julia 程序停止

问题描述

我有一个非常具体且棘手的错误,我无法弄清楚如何修复/解决,我在这里找不到类似的案例。

我有一个 bash 脚本,它在中途调用 Julia 脚本来生成动画帧,然后调用 ffmpeg 来渲染动画。当我从终端运行时,一切都很好。我想自动化这个过程,所以我每天进行一次有趣的随机模拟,所以我将它添加到我的 crontab 中并且它运行——但只是到某个点。动画总是停在一个特定的帧,然后脚本的其余部分继续并吐出被砍掉的动画。

我想也许 cron 是问题所在,所以我安装了 jobber 并从那里运行了作业——使用 jobber,脚本只是停在 Julia 部分。从资源管理器中,我可以看到 Julia 进程仍在使用内存(尽管远低于限制),但它刚刚进入睡眠状态。

我注意到的另一件奇怪的事情是,当我从命令行手动调用脚本时,它在生成动画帧时的运行速度比通过 crontab/jobber 自动运行时快 2-4 倍。

这是一个奇怪的资源问题吗?为了获得更长的动画最初渲染,我不得不修改我的 ulimit 设置,但我更改了配置文件,所以应该为所有内容设置更高的值?我该如何进一步调试和/或纠正它?

如果您想查看正在运行的代码示例(shell 脚本和 julia 脚本都被调用),它在我的 github 上几乎是最新。在 threeBodyProb.jl 文件中,我很确定挂断是由于文件末尾的 for 循环中的 frame 函数。

我正在运行 Linux Mint 19.1 Cinnamon。在此先感谢您的帮助!

这是 bash 脚本挂起的部分:

./threeBodyProb.jl  
echo animation generated, running ffmpeg >> /home/kirk/Documents/3Body/cron_log.txt   
cd tmpPlots  
</dev/null ffmpeg -framerate 30 -i "%06d.png" -c:v libx264 -preset slow -coder 1 -movflags +faststart -g 15 -crf 18 -pix_fmt yuv420p -profile:v high -y -bf 2 -fs 15M -vf "scale=720:720,setdar=1/1" "/home/kirk/Documents/3Body/3Body_fps30.mp4"  

这是挂在 Julia 中的 for 循环:

plotLoadPath="/home/kirk/Documents/3Body/tmpPlots/"
threeBodyAnim=Animation(plotLoadPath,String[])
for i=1:35:length(t)
    gr(legendfontcolor = plot_color(:white)) #legendfontcolor=:white plot arg broken right now (at least in this backend)
    print("$(@sprintf("%.2f",i/length(t)*100)) % complete\r") #output percent tracker
    pos=[plotData[1][i],plotData[2][i],plotData[3][i],plotData[4][i],plotData[5][i],plotData[6][i]] #current pos
    limx,limy=getLims(pos./1.5e11,10) #convert to AU, 10 AU padding
    p=plot(plotData[1][1:i]./1.5e11,plotData[2][1:i]./1.5e11,label="",linecolor=colors[1]) #plot orbits up to i
    p=plot!(plotData[3][1:i]./1.5e11,plotData[4][1:i]./1.5e11,label="",linecolor=colors[2])
    p=plot!(plotData[5][1:i]./1.5e11,plotData[6][1:i]./1.5e11,label="",linecolor=colors[3])
    p=scatter!(starsX,starsY,markercolor=:white,markersize=:1,label="") #fake background stars
    star1=makeCircleVals(rad[1],[plotData[1][i],plotData[2][i]]) #generate circles with appropriate sizes for each star
    star2=makeCircleVals(rad[2],[plotData[3][i],plotData[4][i]]) #at current positions
    star3=makeCircleVals(rad[3],[plotData[5][i],plotData[6][i]])
    p=plot!(star1[1]./1.5e11,star1[2]./1.5e11,label="$(@sprintf("%.1f", m[1]./2e30))",color=colors[1],fill=true) #plot star circles with labels
    p=plot!(star2[1]./1.5e11,star2[2]./1.5e11,label="$(@sprintf("%.1f", m[2]./2e30))",color=colors[2],fill=true)
    p=plot!(star3[1]./1.5e11,star3[2]./1.5e11,label="$(@sprintf("%.1f", m[3]./2e30))",color=colors[3],fill=true)
    p=plot!(background_color=:black,background_color_legend=:transparent,foreground_color_legend=:transparent,
        background_color_outside=:white,aspect_ratio=:equal,legendtitlefontcolor=:white) #formatting for plot frame
    p=plot!(xlabel="x: AU",ylabel="y: AU",title="Random Three Body Problem\nt: $(@sprintf("%0.2f",t[i]/365/24/3600)) yrs after start",
        legend=:best,xaxis=("x: AU",(limx[1],limx[2]),font(9,"Courier")),yaxis=("y: AU",(limy[1],limy[2]),font(9,"Courier")),
        grid=false,titlefont=font(14,"Courier"),size=(720,721),legendfontsize=8,legendtitle="Mass (in solar masses)",legendtitlefontsize=8) #add in axes/title/legend with formatting
    frame(threeBodyAnim,p) #generate the frame
end

如果它有帮助,当从 cron 或 jogger 运行时,它总是生成 407 帧并在第 408 帧失败。

更新:遵循@TasosPapastylianou 在下面的建议,我认为直接在终端中运行而不是从 crontab 或 jobber 等后台进程运行时,问题可能出在不同的 Julia 环境中。当从 crontab/jobber 和直接从命令行运行获取 Julia 环境的测试脚本时,我添加了输出。我不确定这是否是问题所在,以及我是否应该告诉 cron 在这个环境中工作以完成这项工作(尝试在脚本中采购 .bashrc 和 .profile 但这对 env 输出没有影响)。

来自 cron:

SHLVL=1
HOME=/home/kirk
LOGNAME=kirk
_=/home/kirk/bashTest.sh
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=en_US.UTF-8
SHELL=/bin/bash
PWD=/home/kirk
OPENBLAS_MAIN_FREE=1

来自求职者:

MAIL=/var/mail/kirk
USER=kirk
HOME=/home/kirk
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
LOGNAME=kirk
XDG_SESSION_ID=c4
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
XDG_RUNTIME_DIR=/run/user/1000
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/kirk
XDG_DATA_DIRS=/home/kirk/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
OPENBLAS_MAIN_FREE=1

当从命令行手动运行时:

GJS_DEBUG_TOPICS=JS ERROR;JS LOG
LESSOPEN=| /usr/bin/lesspipe %s
PERLBREW_VERSION=0.86
PGPLOT_DIR=/home/kirk/Documents/research/MESA/mesasdk/lib/pgplot
USER=kirk
LANGUAGE=en_US
XDG_SEAT=seat0
SSH_AGENT_PID=1786
XDG_SESSION_TYPE=x11
SHLVL=1
CONDA_SHLVL=0
HOME=/home/kirk
DESKTOP_SESSION=cinnamon
GTK_MODULES=gail:atk-bridge
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
PERLBREW_ROOT=/home/kirk/perl5/perlbrew
PERLBREW_MANPATH=/home/kirk/perl5/perlbrew/perls/perl-5.24.1/man
MESA_DIR=/home/kirk/Documents/research/MESA/mesa-r11701
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
CINNAMON_VERSION=4.0.10
COLORTERM=truecolor
_CE_M=
MANDATORY_PATH=/usr/share/gconf/cinnamon.mandatory.path
QT_QPA_PLATFORMTHEME=qt5ct
HEADAS=/home/kirk/Documents/research/HEASOFT/heasoft-6.26/x86_64-pc-linux-gnu-libc2.27
LOGNAME=kirk
_=./bashTest.sh
DEFAULTS_PATH=/usr/share/gconf/cinnamon.default.path
GIO_EXTRA_MODULES=/usr/lib/x86_64-linux-gnu/gio/modules/
GTK_OVERLAY_SCROLLING=1
XDG_SESSION_ID=c12
TERM=xterm-256color
MESASDK_VERSION=x86_64-linux-20190503
XMM_DIR=/home/kirk/Documents/research/XMM_Newton/xmmsas_20190531_1155
_CE_CONDA=
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
PATH=/home/kirk/Documents/research/MESA/mesasdk/bin:/home/kirk/anaconda3/bin:/home/kirk/anaconda3/condabin:/home/kirk/perl5/perlbrew/bin:/home/kirk/perl5/perlbrew/perls/perl-5.24.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
GDM_LANG=en_US
PERLBREW_HOME=/home/kirk/.perlbrew
SESSION_MANAGER=local/kirk-Inspiron-7352:@/tmp/.ICE-unix/1709,unix/kirk-Inspiron-7352:/tmp/.ICE-unix/1709
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/bc8ec572_68ae_4d79_88a2_3cb33f74d86c
XDG_RUNTIME_DIR=/run/user/1000
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
DISPLAY=:0
VALGRIND_LIB=/home/kirk/Documents/research/MESA/mesasdk/lib/valgrind
LANG=en_US.UTF-8
XDG_CURRENT_DESKTOP=X-Cinnamon
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
PERLBREW_PATH=/home/kirk/perl5/perlbrew/bin:/home/kirk/perl5/perlbrew/perls/perl-5.24.1/bin
XDG_SESSION_DESKTOP=cinnamon
GNOME_TERMINAL_SERVICE=:1.62
XAUTHORITY=/home/kirk/.Xauthority
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/kirk
MESASDK_ROOT=/home/kirk/Documents/research/MESA/mesasdk
CONDA_PYTHON_EXE=/home/kirk/anaconda3/bin/python
SHELL=/bin/bash
QT_ACCESSIBILITY=1
GDMSESSION=cinnamon
LESSCLOSE=/usr/bin/lesspipe %s %s
QT_LOGGING_RULES=qt5ct.debug=false
PERLBREW_PERL=perl-5.24.1
GJS_DEBUG_OUTPUT=stderr
GPG_AGENT_INFO=/run/user/1000/gnupg/S.gpg-agent:0:1
XDG_VTNR=7
PWD=/home/kirk
CONDA_EXE=/home/kirk/anaconda3/bin/conda
XDG_DATA_DIRS=/usr/share/cinnamon:/usr/share/gnome:/home/kirk/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
XDG_CONFIG_DIRS=/etc/xdg/xdg-cinnamon:/etc/xdg
OMP_NUM_THREADS=2
PERLBREW_SHELLRC_VERSION=0.82
VTE_VERSION=5202
MANPATH=/home/kirk/Documents/research/MESA/mesasdk/share/man:/home/kirk/perl5/perlbrew/perls/perl-5.24.1/man:/usr/local/man:/usr/local/share/man:/usr/share/man
OPENBLAS_MAIN_FREE=1

更新 2:再次遵循@TasosPapastylianou 的建议,在告诉 Julia 脚本在从 crontab 运行时记录任何错误后,当它尝试生成帧 408 时,我得到以下堆栈跟踪:

ERROR: LoadError: SystemError: opening file "/tmp/juliaFCI2yw.png": No such file or directory
Stacktrace:
 [1] #systemerror#43(::Nothing, ::Function, ::String, ::Bool) at ./error.jl:134
 [2] systemerror at ./error.jl:134 [inlined]
 [3] #open#309(::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Function, ::String) at ./iostream.jl:289
 [4] open at ./iostream.jl:281 [inlined]
 [5] #open#310(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::getfield(Base, Symbol("##274#275")){String}, ::String) at ./iostream.jl:373
 [6] open at ./iostream.jl:373 [inlined]
 [7] read at ./io.jl:297 [inlined]
 [8] _show(::IOStream, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.GRBackend}) at /home/kirk/.julia/packages/Plots/h3o4c/src/backends/gr.jl:1603
 [9] show(::IOStream, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.GRBackend}) at /home/kirk/.julia/packages/Plots/h3o4c/src/output.jl:198
 [10] png(::Plots.Plot{Plots.GRBackend}, ::String) at /home/kirk/.julia/packages/Plots/h3o4c/src/output.jl:8
 [11] frame(::Animation, ::Plots.Plot{Plots.GRBackend}) at /home/kirk/.julia/packages/Plots/h3o4c/src/animation.jl:20
 [12] top-level scope at /home/kirk/Documents/3Body/threeBodyProb.jl:265
 [13] include at ./boot.jl:326 [inlined]
 [14] include_relative(::Module, ::String) at ./loading.jl:1038
 [15] include(::Module, ::String) at ./sysimg.jl:29
 [16] exec_options(::Base.JLOptions) at ./client.jl:267
 [17] _start() at ./client.jl:436

我不确定如何诊断 - cron 是否限制进程可以创建的文件数量或类似的东西?在我的 bash 脚本中,我还手动添加了以下设置(以防万一),但这仍然导致上面的堆栈跟踪:

ulimit -n 4096  
ulimit -t unlimited 

标签: bashcronjulia

解决方案


Thanks so much for the help @TasosPapastylianou--that error message eventually led me to this post which fixed my problem (and also significantly sped up the animation rendering process as a nice byproduct).

Ultimately it appears the problem was not with cron or the bash script, but instead with Julia's GR backend. I added the line

GR.inline("png")

To the top of the for loop generating the plots to explicitly tell it I was making png files and apparently that fixes everything--not really sure why this is needed and why it's only needed when running from crontab/jobber so if anyone has further insight I'd love to know, but I'm glad it works!

Thanks again to everyone for their help and insights--this tip should be helpful to anyone making animations in a similar way with Julia due to the dramatic improvement in performance that came from this one line!


推荐阅读