我正在学习Linux编程。这是我的代码。我想在子进程中写入并从父进程中读取。似乎有些数据丢失了。我的代码有什么问题吗?
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
int main(int argc, char* argv[]) {
pid_t pid;
char buf[1024];
int link[2];
pipe(link);
pid = fork();
if (pid < 0) {
printf("fork failed\n");
return -1;
} else if(pid == 0) { //child process
//
char buf_child[256];
//dup2(link[1], STDOUT_FILENO);
close(link[0]);
//close(link[1]);
int i;
for(i = 0; i < 10; ++i){
sprintf(buf_child,"current number is : %d", i);
write(link[1], buf_child, sizeof(buf_child));
//sleep(1);
}
printf("[child process] now close pipe write end\n");
close(link[1]);
printf("child process exit...\n");
exit(0);
} else {//parent process
//
close(link[1]);
int nbytes;
while(1) {
printf("[parent process] start read...\n");
nbytes = read(link[0], buf, sizeof(buf));
if(nbytes == -1) {
printf("read failed, reason: %s\n", strerror(errno));
break;
} else if(nbytes != 0){
printf("data: %.*s\n", nbytes, buf);
} else {
printf("parent process: finish read from pipe\n");
break;
}
}
wait(NULL);
}
return 0;
}
输出:
[parent process] start read...
data: current number is : 0
[parent process] start read...
data: current number is : 4
[parent process] start read...
data: current number is : 8
[parent process] start read...
[child process] now close pipe write end
child process exit...
parent process: finish read from pipe
添加sleep语句后,所有数据都可以从父进程读取。
没有数据丢失,您的父进程一次读取 1024 字节,而子进程一次写入 256 字节的缓冲区。父级每次执行
read()
操作时,您都会读取子循环最多 4 次迭代的数据。由于字符串以 NUL 结尾,因此每次打印时,您只会看到第一个字符串,因为 printf
将在第一个终止符处停止打印。
您必须将父级的缓冲区大小更改为
256
或使用不同的机制来读取数据,例如一次读取一个字节,直到看到 NUL \0
字节。后者会更加稳健。您也可以只写入字符串的长度(由 sprintf
返回)。
您收到
"current number is : 0\x00??..??current number is : 1\x00??..??curren..."
其中
??..??
代表 235 个未知字符。
然后打印到第一个 NUL。