障礙
最近需要在一臺(tái) remote 的 gpu 機(jī)器上跑 training 的腳本,terminal 不可能一直開(kāi)著,所以肯定都是要以 daemon 方式來(lái)跑。
眾所周知,最簡(jiǎn)單的 daemon 運(yùn)行的方式就是在命令后加 &,再配合將輸出重定向到一個(gè) log 文件,這樣就可以實(shí)現(xiàn)即以 daemon 跑,也能隨時(shí)查看 output 和error 相關(guān)的信息。比如
./run.sh > output.log &
不過(guò)最近幾天,我發(fā)現(xiàn)每次到公司查看昨晚上的任務(wù)情況,都發(fā)現(xiàn)進(jìn)程在我下班后不久就被干掉,output.log 中也沒(méi)有任何的錯(cuò)誤信息。實(shí)在是相當(dāng)詭異。
求索
google 了一番,沒(méi)什么有建設(shè)性的意見(jiàn),一開(kāi)始以為是不是 & 方式的 daemon 天生有缺陷,還研究半天怎么用 python fork 出 daemon process。但越試越感覺(jué),可能這個(gè)不是主要原因,在玩了幾次 python-daemon 之后,還是決定回到源頭嘗試解決。
其中有一個(gè)回答提到了可能因?yàn)槟_本占用內(nèi)存過(guò)大導(dǎo)致被系統(tǒng) kill 掉(OOM),這個(gè)時(shí)候腳本本身是不會(huì)輸出錯(cuò)誤的。于是就去 /var/log/system.log 里邊兒翻 OOM,結(jié)果 OOM 沒(méi)翻到到翻到了一個(gè) "Received SIGRTMIN+24 from PID 27041 (kill)." , 繼續(xù) google 了一下發(fā)現(xiàn)。這是系統(tǒng)進(jìn)程 systemd 發(fā)出的信號(hào),(systemd 可以理解為調(diào)度 daemon process 的進(jìn)程)。
為什么 systemd 沒(méi)事兒會(huì)來(lái)干我的腳本呢? 因?yàn)?systemd 默認(rèn)會(huì)在一個(gè) user detach 的時(shí)候,干掉這個(gè) user 啟動(dòng)的所有 process,不管你是不是 daemon。所以當(dāng)我的本地電腦休眠超過(guò)一定時(shí)間時(shí),遠(yuǎn)程的機(jī)器自動(dòng) logout user, 然后觸發(fā) systemd 干掉了我的腳本,即便我的腳本有 & 加持。
解題
知道問(wèn)題的原因那就簡(jiǎn)單了,簡(jiǎn)單 google 一下就能知道, 我們只需要修改 /etc/systemd/logind.conf 中,將 KillUserProcesses=no 反 comment 即可。代表讓 systemd 不要干掉 user process。