使用fork()创建多个进程,与管道通信而不使用exit()或wait()

时间:2017-02-27 10:59:36

标签: c++ unix process pipe fork

wait(),exit()和信号被禁止 只允许管道 用户给出一个整数正数-N和N个进程被创建,父创建一个子,该子成为父亲并创建另一个子等等。第一个进程(N-1)中的每一个应该等待首先完成其进程 - 子进程然后自己。初始流程应打印" 1-My Process ID:",下一个创建过程的过程" 2我的进程ID:以及我父亲的ID: "等等。 我的代码。我没有等待或退出而是使用return(-1)。 但我没有设法相应地打印数字 1我的进程ID ...,2我的进程ID ...,3我的进程ID ...所以o n 。 任何想法?

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
/* Read characters from the pipe and echo them to stdout. */

void read_from_pipe (int file)
{
    FILE *stream;
    int c;
    stream = fdopen (file, "r");
    while ((c = fgetc (stream)) != EOF)
    putchar (c);
    fclose (stream);
}

/* Write some random text to the pipe. */

void write_to_pipe (int file)
{
    FILE *stream;
    stream = fdopen (file, "w");
    fprintf (stream, "\n");
    fprintf (stream, " ");
    fclose (stream);
}

int main (void)
{
    pid_t pid;
    int mypipe[2];
    int j = 1;
    int i;

    cout << "\nassume father is by default the first process\n" << "Please enter how child-processes you want: ";
    cin >> i;

    for( ; j < i; j++)
    {

        /* Create the pipe. */
        if (pipe (mypipe))
        {
            fprintf (stderr, "Pipe failed.\n");
            return (-1);
        }

        /* Create the child process. */
         pid = fork ();
        if (pid == (pid_t) 0)
        {
            /* This is the child process. Close other end first. */
            pid = getpid();       
            close (mypipe[1]);
            read_from_pipe (mypipe[0]);
            printf("Child's ID: %d\n",pid);       
            sleep(0);
        }
        else if (pid > (pid_t) 0)
        {
            /* This is the parent process. Close other end first. */
            pid = getpid();        
            close (mypipe[0]);
            write_to_pipe (mypipe[1]);
            printf("Dad's ID: %d\n",pid); 
            sleep(0);
        }
        else 
        {
            /* The fork failed. */
            fprintf (stderr, "Fork failed.\n");
            return (-1);
        }

    }//end for 
    //close (mypipe[0]);
    //write_to_pipe (mypipe[1]); 
   // printf("Dad's ID: %d\n",pid); 
    return (-1);
}// EOP

1 个答案:

答案 0 :(得分:1)

递归可能比迭代更简单,因为您希望每个孩子反过来创建另一个孩子。避免wait的诀窍是让每个读取管道的读取端,并让子进程在返回之前关闭写结束而不写任何东西。因为读取将被阻止,直到写入任何内容或者另一端被关闭。

您无法确定进程实际结束的顺序,因为您没有调用wait,但您确定父进程在其子进程终止之前无法结束。

代码可以是:

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>

using std::cout;
using std::cin;
using std::cerr;
using std::endl;

int start_child(int i, int j) {
    int my_pipe[2];
    pid_t parent_pid, pid;
    /* Create the pipe. */
    if (pipe (my_pipe))
    {
    cerr << "Pipe failed." << endl;
    return (-1);
    }

    /* Create the child process. */
    parent_pid = getpid();
    pid = fork ();
    if (pid == (pid_t) 0) {
    /* child */
    pid = getpid();
    close(my_pipe[0]);
    cout << "I'm child " << j <<  "- my pid is " << pid <<
        " - my parent's pid is " << parent_pid << endl;
    if (i > 1) start_child(i - 1, j + 1);
    if (pid == getpid()) cout << "End of child "<< j << endl;
    close(my_pipe[1]);
    }
    else if (pid == (pid_t) -1) {
    perror("forking");
    close(my_pipe[0]);
    close(my_pipe[1]);
    return -1;
    }
    else {
    /* parent */
    close(my_pipe[1]);
    char buf[2];
    read(my_pipe[0], buf, 2); // wait for the child to close its pipe end
    close(my_pipe[0]);
    }
    return 0;
}



int main (void)
{
    pid_t pid = getpid();
    int i;

    cout << "\nassume father is by default the first process\n" << "Please enter how child-processes you want: ";
    cin >> i;

    cout << "I'm parent - my pid is " << pid << endl;

    int cr = start_child(i, 1);
    if (pid == getpid()) cout << "End of parent" << endl;
    return cr;
}// EOP