nohup后台串行挂起程序
用gpu跑深度学习的程序时,因为只有一块卡,只能一个时间训练一个任务,又想让任务充分利用晚上的时间去跑,所以就想在后台挂起两个任务,一个跑完以后,另一个接着跑,将这两个任务写在一个shell脚本run.sh里面,运行这个shell脚本。这时就有一个问题了,我是在shell脚本外面用nohup呢,还是里面用nohup呢,还是里面和外面都用呢?
也就是说,下面哪种方法是正确的呢:
1、在外面用nohup:nohup bash run.sh >method1.log 2>&1 &
run.sh:
python main1.py
python main2.py
2、在里面用nohup:bash run.sh > method2.log
run.sh:
nohup python main1.py >python1.log 2>&1 &
nohup python main2.py >python2.log 2>&1 &
3、里面和外面都用nohup:nohup bash run.sh >method3.log 2>&1 &
run.sh:
nohup python main1.py >python1.log 2>&1 &
nohup python main2.py >python2.log 2>&1 &
答案是方法1.
下面进行一下解释,首先是nohup的介绍,一下部分参考https://www.cnblogs.com/jinxiao-pu/p/9131057.html
nohup
nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。
nohup 是 no hang up 的缩写,就是不挂断的意思。
nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不能结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。
在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中。
案例
1. nohup command > myout.file 2>&1 &
在上面的例子中,0 – stdin (standard input),1 – stdout (standard output),2 – stderr (standard error) ;
2>&1是将标准错误(2)重定向到标准输出(&1),标准输出(&1)再被重定向输入到myout.file文件中。
2. 0 22 * * * /usr/bin/python /home/pu/download_pdf/download_dfcf_pdf_to_oss.py > /home/pu/download_pdf/download_dfcf_pdf_to_oss.log 2>&1
这是放在crontab中的定时任务,晚上22点时候怕这个任务,启动这个python的脚本,并把日志写在download_dfcf_pdf_to_oss.log文件中
nohup和&的区别
& : 指在后台运行
nohup : 不挂断的运行,注意并没有后台运行的功能,就是指,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,例如我们断开SSH连接都不会影响他的运行,注意了nohup没有后台运行的意思;&才是后台运行
&是指在后台运行,但当用户推出(挂起)的时候,命令自动也跟着退出
那么,我们可以巧妙的吧他们结合起来用就是
nohup COMMAND &
这样就能使命令永久的在后台执行
例如:
1. sh test.sh &
将sh test.sh任务放到后台 ,即使关闭xshell退出当前session依然继续运行,但标准输出和标准错误信息会丢失(缺少的日志的输出)
将sh test.sh任务放到后台 ,关闭xshell,对应的任务也跟着停止。
2. nohup sh test.sh
将sh test.sh任务放到后台,关闭标准输入,终端不再能够接收任何输入(标准输入),重定向标准输出和标准错误到当前目录下的nohup.out文件,即使关闭xshell退出当前session依然继续运行。
3. nohup sh test.sh &
将sh test.sh任务放到后台,但是依然可以使用标准输入,终端能够接收任何输入,重定向标准输出和标准错误到当前目录下的nohup.out文件,即使关闭xshell退出当前session依然继续运行。
所以,解释一下上面的3个方法,笔者做过实验后得出的结论:
首先方法1,用nohup可以使命令永久的执行下去,并且&使shell程序挂在了后台,执行完第一个python main1.py以后,才会执行python main2.py,顺利达到了串行的目的
方法2,bash run.sh > method2.log没有挂后台,但是里面都用了nohup,其实结果和方法3是一样的,看到里面的两个任务都挂了起来,ctr+c结束bash run.sh > method2.log这个指令以后,两个任务都在跑,而并没有排队
如上图所示,里面外面都用nohup,结果两个python的任务都挂上了,并没有排队,而是一起塞给了gpu,可是gpu没有那么大的能力让这两个同时执行啊,所以出现下面这种现象,你看,这是那个第二个挂起来的训练模型,它不动,只有第一个在训练,这时的gpu占用率已经达到了最高,但是任务二,只是占用着资源,不进行训练,这样的话,还会拖慢第一个任务的训练效率。果然过了一会资源不够,他把第二个任务自动kill掉了
方法3和方法2的效果是一样的,只是方法3是将bash run.sh > method3.log挂在了后台而已,效果上是一样的。所以为了更高效的利用gpu进行训练,要把nohup放在外面,里面不能放nohup。
总结一下,因为nohup是把东西塞到后台,也就是说我如果在里面加nohup的话,是达不到两个串行运行的效果的,而是两个任务一起进行,如果资源不够,那么一个会被kill掉的。所以要达到串行的目的,shell脚本里面不能加nohup,只能在外面加nohup达到挂在后台,关掉终端也会继续按顺序执行的效果