我有一个程序,它需要做大量的工作(大约需要4-5个小时),当它可以使用的所有数据都可用时,它就会由cron启动。有时,当我等待它完成时,我希望能够在完成时启动另一个(交互式)程序。等待电话看起来很有希望,但只会等待孩子。
ipc
进程间通信来沿着这些思路做一些事情。man ipc
。
我有一个程序,它需要做大量的工作(大约需要4-5个小时),当它可以使用的所有数据都可用时,它就会由cron启动。有时,当我等待它完成时,我希望能够在完成时启动另一个(交互式)程序。等待电话看起来很有希望,但只会等待孩子。
ipc
进程间通信来沿着这些思路做一些事情。man ipc
。
Answers:
我绝对喜欢EDIT#3解决方案(请参见下面的内容)。
如果它不在同一个shell中,请使用while循环,条件是ps -p返回true。把睡眠中循环,以减少处理器的使用。
while ps -p <pid> >/dev/null 2>&1
do
sleep 10
done
或者您的UNIX支持/ proc(例如,HP-UX仍然不支持)。
while [[ -d /proc/<pid> ]]
do
sleep 10
done
如果要超时
timeout=6 # timeout after 1mn
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
sleep 10
((timeout -= 1))
done
还有另一种方法:不要使用cron。使用批处理命令来堆叠您的作业。
例如,您可以每天堆放所有工作。可以对批处理进行调整,以允许某些并行性,因此阻止的作业不会停止所有堆栈(取决于操作系统)。
在您的主目录中创建一个fifo:
$ mkfifo ~/tata
在工作结束时:
echo "it's done" > ~/tata
在另一项工作(正在等待的工作)开始时:
cat ~/tata
这不是在轮询它是旧的好阻塞IO。
使用信号:
在等待脚本的开头:
echo $$ >>~/WeAreStopped
kill -STOP $$
在您的长期工作结束时:
if [[ -f ~/WeAreStopped ]] ; then
xargs kill -CONT < ~/WeAreStopped
rm ~/WeAreStopped
fi
您可以修改cron作业以使用某些标志。
代替
2 2 * * * /path/my_binary
您可以使用
2 2 * * * touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running
只需用脚本甚至手动监视此文件。如果存在,则您的程序正在运行;否则,您可以随意做任何您想做的事情。
脚本样本:
while [[ -f /tmp/i_m_running ]] ; do
sleep 10 ;
done
launch_whatever_you_want
如果您不喜欢使用sleep
,则可以每X分钟修改一次脚本并通过cron运行它。
在这种情况下,脚本示例将为:
[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want
这种方式稍微容易一些,因为您不必查找cron进程的PID。
除了父进程等待其子进程之一完成之外,没有其他进程可以等待进程完成。如果可以,请通过脚本启动程序:
do_large_amount_of_work
start_interactive_program
如果您无法执行此操作,例如,在要从cron作业开始大量工作,但要从会话上下文开始交互式程序之前,那么请执行此操作
do_large_amount_of_work
notify_completion
有几种实现方法notify_completion
。某些桌面环境提供了一种通知机制(在远程X显示器上打开一个窗口(为什么“无法打开显示器”?可能有用)?您也可以使用文件更改通知来创建一个。在Linux上,文件更改通知工具是inotify。
do_large_amount_of_work
echo $? >/path/to/finished.stamp
对创建的反应/path/to/finished.stamp
:
inotifywait -e close_write -q /path/to/finished.stamp
start_interactive_program
如果您无法更改do_large_amount_of_work
调用方式,但是您知道它最后修改的文件,则可以使用相同的机制在关闭该文件时做出反应。您还可以对其他事件做出反应,例如重命名文件(inotifywait
有关可能的列表,请参见手册)。