【Linux 编程基础 · 多进程实验(三)】利用fork()创建3个子进程:第1个子进程打印“Hello World”;第2个子进程计算2的8次方,并且打印结果;第3个子进程尝试打印5/0的结果。父

题目

利用 fork() 创建 3 个子进程:第 1 个子进程打印 “Hello World”;第 2 个子进程计算 2 的 8 次方,并且打印结果;第 3 个子进程尝试打印 5 / 0 的结果。父进程利用轮询方法非阻塞式地等待 3 个子进程结束,并且打印子进程的结束信息。

点拨

waitpid() 等待一个指定的进程或进程组的状态改变。默认情况下,它只在指定的进程(组)被终止后返回。可以通过传递相应的参数来改变其行为。该函数返回状态改变的子进程 ID。若出错,返回 -1。如果指定了参数(宏)WNOHANG,且第一个参数 pid 指定的一个或多个子进程存在,但未改变其状态,则返回 0。
WNOHANG | WUNTRACED | WCONTINUED 指定 waitpid() 在无子进程退出时立刻返回、在子进程被暂停时返回、在子进程因为 SIGCONT 继续运行时返回。
宏 WIFEXITED 判定指定的状态变量是否表示进程正常退出。WEXITSTATUS 可以从状态变量读出子进程的退出状态。
WIFSIGNALED 表示进程是否被信号终止。配合 WTERMSIG 可以获得使进程(异常)终止的信号。
WIFSTOPPED 表示进程是否被暂停。配合 WSTOPSIG 可以获得使进程暂停的信号。

源代码

#include <cmath>
#include <cstring>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

const size_t CHILDREN_COUNT = 3;
pid_t child[CHILDREN_COUNT];
pid_t terminate_child[CHILDREN_COUNT];
int end_state[CHILDREN_COUNT];

int main() {
    
    
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    child[0] = fork();
    if (child[0] == 0) {
    
    
        cout << getpid() << ": Hello World" << endl;
        return 0;
    }

    child[1] = fork();
    if (child[1] == 0) {
    
    
        cout << getpid() << ": pow(2, 8) = " << pow(2, 8) << endl;
        return 0;
    }

    child[2] = fork();
    if (child[2] == 0) {
    
    
        cout << getpid() << ": 5 / 0 = " << 5 / 0 << endl;
        return 0;
    }

    for (size_t i = CHILDREN_COUNT, j = 0; i; ++j) {
    
    
        if (j == CHILDREN_COUNT) j = 0;
        terminate_child[j] = waitpid(child[j], &end_state[j], WNOHANG | WUNTRACED | WCONTINUED);
        if (terminate_child[j] > 0) {
    
    
            cout << "--------------------------------" << endl;
            cout << "Child process " << terminate_child[j] << " has ended. " << endl;
            if (WIFEXITED(end_state[j])) cout << "Normally exited. Status: " << WEXITSTATUS(end_state[j]) << endl;
            else if (WIFSIGNALED(end_state[j])) cout << "EXCEPTION: Killed by signal " << WTERMSIG(end_state[j]) << ": " << strsignal(WTERMSIG(end_state[j])) << endl;
            else if (WIFSTOPPED(end_state[j])) cout << "Paused by signal " << WSTOPSIG(end_state[j]) << endl;
            cout << "Remaining child(ren) count: " << --i << endl;
            cout << "--------------------------------" << endl;
        }
    }

    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/COFACTOR/article/details/117152730
今日推荐