简体   繁体   English

如何使两个子进程互相等待

[英]how to make two child processes waiting for each other

I am studying about processes in operating systems. 我正在研究操作系统中的进程。 I came up with a question in which I have to create two child processes to do similar task using fork and wait. 我想到一个问题,我必须创建两个子进程才能使用fork和wait执行相似的任务。 After the parent fork the first child, that child will wait until parent fork another one and the second child finish its job. 在父母分叉第一个孩子之后,该孩子将等到父母分叉另一个孩子,第二个孩子完成工作。

For example, if I want the first child displays 10 first even numbers and the second child displays 10 first odd number, the output should be like this: 例如,如果我希望第一个孩子显示10个第一个偶数,而第二个孩子显示10个第一个奇数,则输出应如下所示:

Second child 1 3 5 7 9 11 13 15 17 19 second child dies First child 2 4 6 8 10 12 14 16 18 20 first child dies 第二个孩子1 3 5 7 9 11 13 15 17 19第二个孩子去世第一个孩子2 4 6 8 10 12 14 16 18 20

end! 结束!

I've been trying various ways but I couldn't make the first child wait until the second child finishing its job. 我一直在尝试各种方法,但是我不能让第一个孩子等到第二个孩子完成工作。 Does anybody know how to do it? 有人知道怎么做吗? Thanks 谢谢

These are not optimal, but will do the trick : 这些不是最佳方法,但是可以解决问题:

First, option use a shared object : 首先,选项使用共享对象:
- You can use mmap to create a shared memory area, (see man mmap) -您可以使用mmap创建共享内存区域,(请参阅man mmap)
- You can use shmget and shmat function family -您可以使用shmget和shmat函数系列
- Hence you'll get each other PID and be able to use wait (man 2 wait) -因此,您将获得彼此的PID,并能够使用wait(man 2 wait)

Second option: 第二种选择:
- The parent knows the PID of both children. -父母知道两个孩子的PID。
- The parent will send signals to both children, one by one. -父母将一对一地向两个孩子发送信号。 (see man 2 kill (and don't send KILL signal, please)) (请参见杀手2(请不要发送KILL信号))
- Each child will have a custom parent, and do something with this signal. -每个孩子都会有一个自定义的父母,并对此信号进行处理。

Given the example you've provided, I'm thinking of two problems that you need to deal with using a combination of system calls and C-library calls: 给定您提供的示例,我正在考虑使用系统调用和C库调用的组合来处理的两个问题:

  1. Picking an interprocess resource that can be used to notify a process from another. 选择一个进程间资源,该资源可用于通知另一个进程。
  2. Flushing your output stream without using a newline (seeing how your example output is formatted). 不使用换行符就刷新输出流(查看示例输出的格式)。

Solving the first problem is dependent on the operating system that you want to implement this for. 解决第一个问题取决于要为其实现此功能的操作系统。 Typically POSIX compliant operating systems will provide a few mechanisms that can be used for this. 通常,符合POSIX的操作系统将提供一些可用于此目的的机制。 These mechanisms are likely to include process control, pipes, sockets, signals, semaphores, shared memory, file operations, and message passing. 这些机制可能包括过程控制,管道,套接字,信号,信号量,共享内存,文件操作和消息传递。 Non-POSIX compliant systems may also have some of these mechanisms or similar that can be used but for the sake of this answer I'll stick with the target OS being a POSIX-compliant Unix-like OS. 不符合POSIX的系统也可以使用其中一些机制或类似机制,但是出于这个答案,我将目标操作系统坚持为POSIX兼容的类Unix操作系统。

The second problem is more simply just a matter of knowing how to flush the output stream that the code uses. 第二个问题仅是知道如何刷新代码使用的输出流的问题。 The C-library standard IO stream and the fflush call can serve for this. C库标准IO流和fflush调用可用于此目的。

Here's some code I whipped up that puts this together, compiles for me, and gives the output you showed: 这是我整理的一些代码,将它们组合在一起,为我编译,并提供您显示的输出:

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {
            const int use_sig = SIGUSR1;
            pid_t child1 = fork();
            if (child1 == 0)
            {
                    sigset_t set;
                    sigemptyset(&set);
                    sigaddset(&set, use_sig);
                    int sig;
                    do
                    {
                            sigwait(&set, &sig);
                    } while (sig != use_sig);
                    printf("First child ");
                    printf("2 4 6 8 10 12 14 16 18 20");
                    printf(" first child dies");
                    fflush(NULL);
                    return 0;
            }
            pid_t child2 = fork();
            if (child2 == 0)
            {
                    printf("Second child ");
                    printf("1 3 5 7 9 11 13 15 17 19 ");
                    printf("second child dies ");
                    fflush(NULL);
                    kill(child1, use_sig);
                    return 0;
            }
            for (;;)
            {
                    int status;
                    pid_t pid = wait(&status);
                    if (pid == child1)
                    {
                            child1 = 0;
                    }
                    else if (pid == child2)
                    {
                            child2 = 0;
                    }
                    if (child1 == 0 && child2 == 0)
                    {
                            break;
                    }
            }
            printf("\n");
            exit(EXIT_SUCCESS);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM