0

情况就是这样,我有其他人编写的可执行文件随机死亡,解决它的方法是重新启动作业最多 3 次(总共 4 次)。我还需要并行运行 6 个具有不同输入的可执行文件副本。可执行文件也可能需要数小时才能运行。可执行文件通过 bourne shell 脚本运行(不是 bash,由于遗留原因,我无法切换到 bash 或其他 shell)。目前,bourne shell 脚本同时启动 6 个运行,等待它们全部完成或死亡,然后重新启动任何已经死亡的,并等待它们全部完成或死亡,然后重新启动任何已经死亡的时间等等。

我的想法是在 bourne shell 脚本中编写一个函数,该函数启动 6 次运行中的 1 次,等待它完成或死亡,如果它死亡,立即重新启动该运行,同时使用 while 循环调用启动/重新启动函数一个 & 让它在后台运行,并在 while 循环结束后等待,让它等到 launch-relaunch 函数的所有并行执行完成,然后并行处理脚本的其余部分。

这没有按预期运行。它似乎在后台并行运行启动/重新启动功能的所有副本,但 while 循环结束时的等待并没有延迟脚本其余部分的执行,因为逻辑检查了一个它由可执行文件生成的文件。

所以有人可以通过提供一个示例脚本来帮助我,说明如何并行启动 6 个可执行文件,并且每个可执行文件在完成后立即重新启动 3 次,假设可执行文件采用一个命令行参数来指示输入文件的名称读入和要写出的输出文件的名称。

谢谢

编辑:这是一个模拟的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

谢谢

4

0 回答 0