【问题标题】:Creating 3 children processes and exiting them after a specified number of seconds创建 3 个子进程并在指定秒数后退出它们
【发布时间】:2019-02-12 17:54:31
【问题描述】:

输出应该是什么样子的图像:我的问题是我需要编写一个程序来接受 3 个进程的名称作为命令行参数。这些进程中的每一个都将运行与:(PID%10)*3+5 一样多的秒数并终止。在这 3 个子进程终止后,父进程 将重新安排每个孩子。当所有孩子都被重新安排了 3 次时,父母将终止。我已经使用 fork 创建了三个孩子,但正在努力让他们以特定标准退出?

using namespace std;

int main(){
    int i;
    int pid;
    for(i=0;i<3;i++) // loop will run n times (n=3)
    {
        if(fork() == 0)
        {
            pid = getpid();
            cout << "Process p" << i+1 << " pid:" << pid << " Started..." << endl;
            exit(0);
        }
    }
    for(int i=0;i<5;i++) // loop will run n times (n=3)
    wait(NULL);

  }

【问题讨论】:

  • 您是否尝试过让 one 子进程以该条件终止?还是更简单的条件?什么是症结所在?
  • 所以我只是简单地设置子进程应该运行的时间,我不熟悉任何指定进程运行然后终止的时间(以秒为单位)的函数
  • 在退出之前尝试为每个孩子使用sleep()。它将暂停该过程几秒钟
  • 我在帖子开头添加了一个链接,以便您更好地了解我想要做什么。也许我没有把它描述得最好

标签: c++ linux operating-system child-process


【解决方案1】:

您可以使用sigtimedwait 等待SIGCHLD 或超时。

工作示例:

#include <cstdio>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>

template<class... Args>
void start_child(unsigned max_runtime_sec, Args... args) {
    // Block SIGCHLD.
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigprocmask(SIG_BLOCK, &set, nullptr);
    // Enable SIGCHLD.
    signal(SIGCHLD, [](int){});

    pid_t child_pid = fork();
    switch(child_pid) {
    case -1:
        std::abort();
    case 0: {
        // Child process.
        execl(args..., nullptr);
        abort(); // never get here.
    }
    default: {
        // paren process.
        timespec timeout = {};
        timeout.tv_sec = max_runtime_sec;
        siginfo_t info = {};
        int rc = sigtimedwait(&set, nullptr, &timeout);
        if(SIGCHLD == rc) {
            std::printf("child %u terminated in time with return code %d.\n", static_cast<unsigned>(child_pid), info.si_status);
        }
        else {
            kill(child_pid, SIGTERM);
            sigwaitinfo(&set, &info);
            std::printf("child %u terminated on timeout with return code %d.\n", static_cast<unsigned>(child_pid), info.si_status);
        }
    }
    }
}

int main() {
    start_child(2, "/bin/sleep", "/bin/sleep", "10");
    start_child(2, "/bin/sleep", "/bin/sleep", "1");
}

输出:

child 31548 terminated on timeout with return code 15.
child 31549 terminated in time with return code 0.

【讨论】:

    【解决方案2】:

    通过这些更改,您的程序会产生所需的输出:

    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <iostream>
    using namespace std;
    
    int main()
    {
        for (int round = 0; ++round <= 4; )
        {
            int i;
            cout << "*** ROUND: " << round << " ***\n";
            for (i=0; i<3; i++) // loop will run n times (n=3)
            {
                if (fork() == 0)
                {
                    int pid = getpid();
                    cout << "Process p" << i+1 << " pid:" << pid << " started...\n";
                    unsigned int seconds = pid%10*3+5;
                    cout << "Process " << pid << " exiting after "
                         << seconds-sleep(seconds) << " seconds\n";
                    exit(0);
                }
            }
            while (i--) // loop will run n times (n=3)
            {
                int status;
                cout << "Process " << wait(&status);
                cout << " exited with status: " << status << endl;
            }
        }
    }
    
    • 正如 Serge 建议的那样,我们在退出之前为每个孩子使用sleep()。它将暂停该过程几秒钟
    • 要获取实际状态信息,我们调用wait(&amp;status) 而不是wait(NULL)
    • 我们正在为第一轮调度以及所需的 3 次重新调度进行这一切。

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      相关资源
      最近更新 更多