无法让 'child' & 'parent' 正常通信
Can't get the 'child' & 'parent' communicate together properly
我正在尝试在 C
中开发电梯模拟器应用程序,为此我将同时使用共享内存和管道进行进程间通信。
为了让我的生活更轻松一些,我声明了两个名为 read_from_pipe
和 write_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
但是我得到一个空白屏幕。
知道我做错了什么吗?
调用 fork()
后有 3 种可能性
1)返回值<0,表示fork()失败
2) 返回值为0表示child正在执行
3) 返回值 >0 表示 parent 正在执行。
假设没有发生故障,那么 parent 和 child 都在执行调用 fork()
之后的代码。所以 parent 和 child 都在调用 open()
和 mmap()
。
需要检查 open() 和 mmap() 的返回值以确保操作成功。
发布的代码中未使用 mmap() 结果。
已发布的代码中未使用 open() 结果。
行:fprintf(stderr, "Fork failed.\n");
可能是对 perror()
的调用,因此也会显示系统错误消息。
问题的根源似乎是竞争条件。
建议使用 read()
而不是 fgetc()
,因为读取将等待所需数量的字符,因此将等待传递的数据可用。请务必检查 read()
的返回值并在循环中重试,直到返回值为 0(或错误小于 0)
我正在尝试在 C
中开发电梯模拟器应用程序,为此我将同时使用共享内存和管道进行进程间通信。
为了让我的生活更轻松一些,我声明了两个名为 read_from_pipe
和 write_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
但是我得到一个空白屏幕。
知道我做错了什么吗?
调用 fork()
后有 3 种可能性
1)返回值<0,表示fork()失败
2) 返回值为0表示child正在执行
3) 返回值 >0 表示 parent 正在执行。
假设没有发生故障,那么 parent 和 child 都在执行调用 fork()
之后的代码。所以 parent 和 child 都在调用 open()
和 mmap()
。
需要检查 open() 和 mmap() 的返回值以确保操作成功。
发布的代码中未使用 mmap() 结果。
已发布的代码中未使用 open() 结果。
行:fprintf(stderr, "Fork failed.\n");
可能是对 perror()
的调用,因此也会显示系统错误消息。
问题的根源似乎是竞争条件。
建议使用 read()
而不是 fgetc()
,因为读取将等待所需数量的字符,因此将等待传递的数据可用。请务必检查 read()
的返回值并在循环中重试,直到返回值为 0(或错误小于 0)