状況は次のとおりです。他の誰かが作成した実行可能ファイルがランダムに死んでしまい、それを回避する方法は、ジョブを最大 3 回 (合計 4 回) 再起動することです。また、実行可能ファイルの 6 つのコピーを異なる入力で並行して実行する必要もあります。実行可能ファイルの実行には数時間かかることもあります。実行可能ファイルは bourne シェル スクリプトを介して実行されています (bash ではありません。従来の理由から、bash や別のシェルに切り替えることはできません)。現在、ボーン シェル スクリプトは 6 つの実行を同時に起動し、すべてが完了するか終了するのを待ってから、終了したものを再起動し、すべてが完了するか終了するのを待ってから、すぐに終了したものを再起動します。時間など。
私はボーンシェルスクリプトに関数を書き、6回の実行のうち1回を起動して完了するか停止するのを待ち、停止した場合はすぐにその実行を再起動し、whileループで起動/再起動関数を呼び出します& を使用してバックグラウンドで実行し、while ループの終了後に待機して、launch-relaunch 関数のすべての並列実行が完了するまで待機させてから、スクリプトの残りの部分を並列に処理します。
これは期待どおりに機能していません。起動/再起動関数のすべてのコピーをバックグラウンドで並行して実行しているように見えますが、while ループの最後の待機はスクリプトの残りの実行を遅らせていません。実行可能ファイルによって生成されたファイル。
したがって、6つの実行可能ファイルを並行して起動し、各実行可能ファイルが完了するとすぐに3回再起動される方法のサンプルスクリプトを提供することで、誰かが私を助けることができます。実行可能ファイルが入力ファイルの名前を示すために1つのコマンドライン引数を取ると仮定します読み込む出力ファイルの名前と書き出す出力ファイルの名前。
ありがとう
編集:これはexecutable.cppファイルのモックアップです
#include <ctime>
#include <cstdlib> //for abort()
#include <cstring> //for strcmp()
#include <iostream>
#include <fstream>
#include <sstream>
int main (int argc, char *argv[])
{
if(argc < 2) {
//give instructions
std::cout << "this function requires 1 argument, a process id.\n"
<< "If the optional second command argument has the\n"
<< "value \"die\" the run will die prematurely." << std::endl;
return 1;
}else if(argc>=3) {
//to test the script we need to give this executable the ability to
//die on command
if(strcmp(argv[2],"die")==0) abort();
}
time_t t0; //start time
time_t tc; //current time
double seconds; //seconds between current time and start time
time(&t0); //assign value of the start time
do{
time(&tc); //assign value of the current time
seconds=difftime(tc,t0); //compute the time difference in seconds
} while(seconds<10); //wait until 10 seconds have passed.
std::ostringstream oss;
oss << "proc_" << argv[1] << ".output";
std::ofstream ofs;
ofs.open(oss.str().c_str(),std::ofstream::out);
ofs << "this run completed" << std::endl;
ofs.close();
return 0;
}
これがrunscript.shファイルのモックアップです
#! /bin/sh -ha
executable_name=$1
#---------------------------------------------------------------------
launch_relaunch_func() {
#---------------------------------------------------------------------
process_num=$1
first_attempt_to_not_die=$process_num
if_my_proc_completed_successfully="no"
num_attempts_for_my_proc_so_far=0
max_attempts=4
second_arg="die"
output_fname="proc_${process_num}.output"
while [ "if_my_proc_completed_successfully" = "no" -a \
${num_attempts_for_my_proc_so_far} -lt ${max_attempts} ]; do
num_attempts_for_my_proc_so_far=`expr "${num_attempts_for_my_proc_so_far} + 1"`
if [ ${num_attempts_for_my_proc_so_far} -ge ${first_attempt_to_not_die} ] ; then
second_arg="live"
fi
./${executable_name} ${process_num} ${second_arg}
if [ -s ${output_fname} ] ; then
if_my_proc_completed_successfully="yes"
fi
done
if [ "if_my_proc_completed_successfully" = "no" ] ; then
echo "process ${proc_num} failed on all ${max_attempts} attempts"
echo ${proc_num} >> bad_runs.txt
return 1
fi
echo ${proc_num} >> good_runs.txt
return 0;
}
#---------------------------------------------------------------------
proc_list="1 2 3 4"
num_procs=4;
for proc in ${proc_list} ; do
(launch_relaunch_func $proc) &
done
wait
if [ `ls -1 proc_[0-9].output 2>/dev/null | wc -l` -eq $num_procs ] ; then
echo "all runs completed successfully"
rm -f good_runs.txt bad_runs.txt
else
printf "Success: %d Failed: %d\n" `wc -l good_runs.txt | cut -d \ -f 1` `wc -l bad_runs.txt | cut -d \ -f 1`
exit 2
fi
exit 0
ありがとう