无法获得“孩子”这样的孩子。 &安培; '父'正确地沟通

时间:2015-10-14 01:38:49

标签: c fork ipc

我正在尝试在C中开发一个电梯模拟器应用程序,为此我将使用共享内存和管道进行内部通信。 为了让我的生活更轻松,我宣布了两个名为read_from_pipewrite_to_pipe的函数。

以下是我的main代码的一部分,我需要弄清楚它为什么不按预期运行:

01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
04 #include <sys/types.h>
05 #include <sys/stat.h>
06 #include <fcntl.h>
07 #include <sys/mman.h>
08 
09 #include "windows.h"
10 
11 #define READ 0
12 #define WRITE 1
13 
14 typedef struct lift
15 {
16         int    winch_control;
17         int    door_control;
18         int    call_buttons;
19         int    lift_buttons;
20         double position;
21         double door_ajar;
22         int    quit;
23         int    reset;
24         int    error;
25 } lift;
26 int main(void)
27 {
28  lift *pLift;
29  pid_t pid;
30  off_t   off = 0;
31  int liftfd, mmlen = sizeof(lift), FIFO[2];;
32  
33  pid = fork();
34  liftfd = open("liftfile", (O_CREAT | O_RDWR), 0666 );
35  pLift = (lift *)mmap( (caddr_t)0, mmlen, (PROT_READ | PROT_WRITE),  MAP_SHARED, liftfd, off);
36 
37  if (pipe(FIFO))                 // create pipe failed
38  {
39      fprintf(stderr, "Pipe failed.\n");
40      return EXIT_FAILURE;
41  }
42  
43  if (pid == (pid_t)0)            // child process
44  {   
45      close(FIFO[WRITE]);         
46      read_from_pipe(FIFO[READ]);
47      close(FIFO[READ]);
48  }
49  else if (pid < (pid_t)0)        // create fork failed
50  {
51      fprintf(stderr, "Fork failed.\n");
52      return EXIT_FAILURE;
53  }
54  else                            // parent process
55  {   
56      close(FIFO[READ]);          
57      write_to_pipe(FIFO[WRITE],"UP3" , 56);
58      close(FIFO[WRITE]); 
59  }
60 }

read_from_pipe子程序:

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

write_to_pipe子程序:

void write_to_pipe(int fileDescriptr , char *stateName , int timerValue)
{
    FILE *stream;
    stream = fdopen(fileDescriptr, "w");
    fprintf(stream, "Current system state:\t%s\n", stateName);
    fprintf(stream, "Timer value:\t\t%d\n",timerValue);
    fflush(stream);
    fclose(stream);
}

我想指出的一些事情:

  • 如果有人想引用某个特定内容,我会提供行号 线。我假设每个人都知道如何在代码中使用列模式 编辑并删除它们以便成功编译。
  • 代码中的许多内容最初可能看起来多余,但实际上它们正在代码中的其他地方使用。所以忽略了 如果您选择了任何一种冗余。
  • 我在Windows上使用CygWin。

根据行号57,我的预期结果为:

Current system state:      UP3
Timer value:               56

但是我得到一个空白的屏幕。

知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

致电fork()后,有3种可能性

1)返回值<&lt; 0,表示fork()失败

2)返回值为0表示孩子正在执行

3)返回的值> 0,表示父进程正在执行。

假设没有发生故障,那么父和孩子都在调用fork()之后执行代码。所以父母和孩子都在调用open()mmap()

需要检查open()和mmap()返回的值,以确保操作成功。

mmap()结果未在发布的代码中使用。

open()结果未在发布的代码中使用。

行:fprintf(stderr, "Fork failed.\n");应该是对perror()的调用,因此也会显示系统错误消息。

问题的根源似乎是竞争条件。

建议使用read()而不是fgetc(),因为读取将等待所需的字符数,因此将等待传递的数据可用。请务必检查read()的返回值,然后再循环,直到返回值为0(或错误小于0)