2

We were recently introduced to fork() in my applied OS design class, and I'm not understanding it very well. We need to use it to create four separate processes in C file, and then have three of these processes write to a named pipe, while the fourth reads from it.

This is the code I've tried so far:

// creating the named pipe
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0);
int myPipe;

const char* colour;

pid_t p1, p2;

p1 = fork();
if (p1 < 0)
{
   printf("Fork failed\n");
}
else if (p1 == 0) // this is the child of p1, we'll call it "red"
{
   printf("\nPid %d %s", getpid(), "(red) started\n");
   myPipe = open("/tmp/namedpipe", O_WRONLY);
   colour = "RED\n";
   write(myPipe, colour, strlen(colour) +1);
   close(myPipe);
}
else // the is the parent of p1, we'll call it "green"
{
   printf("\nPid %d %s", getpid(), "(red) started\n");
   myPipe = open("/tmp/namedpipe", O_WRONLY);
   colour = "RED\n";
   write(myPipe, colour, strlen(colour) +1);
   close(myPipe);

   p2 = fork();
   if (p2 < 0)
   {
      printf("Fork failed\n");
   }
   else if (p2 == 0) // this is the child of p2, we'll call it "blue"
   {
      printf("\nPid %d %s", getpid(), "(blue) started\n");
      myPipe = open("/tmp/namedpipe", O_WRONLY);
      colour = "BLU\n";
      write(myPipe, colour, strlen(colour) +1);
      close(myPipe);
   }
   else // the is the parent of p2, we'll call it "reader"
   {
      printf("This is the reader process");
      myPipe = open("/tmp/namedpipe", O_RDONLY);
      char nextChar;
      while (read(myPipe, &nextChar, 1) == 1)
         printf("%c", nextChar);
      close(myPipe);
   }
}

This code seems to work fine if you comment out all the pipe-related statements, but otherwise it executes the first two print statements and then hangs, forcing a CTRL-C. I'm not sure if the problem lies in the forking or if it has to do with the way I'm writing and reading to the pipe. Please let me know.

4

2 回答 2

4

命名管道打开时不会O_NONBLOCK在进程之间同步。如果一个进程试图打开以进行写入,它将阻塞,直到其他进程尝试打开以进行读取。如果顺序颠倒,则读取过程被阻止,直到写入过程尝试打开。无论哪种方式,两个打开都同时成功。

在您的程序中,您创建了一个尝试打开以进行写入的子进程“red”,以及一个也尝试打开以进行写入的父进程“green”。还没有人在读,所以两个都被屏蔽了。没有达到将创建其他 2 个进程的代码,因为它是在阻塞它的“绿色”进程中打开之后出现的。

于 2013-07-25T23:12:27.703 回答
2

你打开管道进行写作。这将阻塞,直到打开管道进行读取。由于父母不会分叉更多的孩子,这一切都停止了。

我无法访问 Unix 平台,所以我没有尝试编译它,但你可以尝试这样事情:

// creating the named pipe
#define CHILD_COUNT 3
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0);
const char* childname[CHILD_COUNT] = { "Red", "Blue", "Yellow" };
const char* colorname[CHILD_COUNT] = { "RED\n", "BLUE\n", "YELLOW\n" };
int myPipe;

const char* colour;

pid_t p;
int i;
for (i=0; i<CHILD_COUNT; i++) 
{
  p = fork();
  if (p < 0) {
    printf("Fork failed\n");
  }
  else if (p == 0) // this is a child, do child stuff
  {
    printf("\nPid %d (%s) started\n", getpid(), childname[i]");
    myPipe = open("/tmp/namedpipe", O_WRONLY);
    colour = colorname[i]; // =="RED\n" for first child
    write(myPipe, colour, strlen(colour) +1);
    close(myPipe);
    return;
  }
  // else it's the parent, spawn more children
}

// Parent
printf("This is the reader process");
myPipe = open("/tmp/namedpipe", O_RDONLY);
char nextChar;
while (read(myPipe, &nextChar, 1) == 1)
    printf("%c", nextChar);
close(myPipe);
于 2013-07-25T23:12:18.593 回答