[英]Read and write using pipes
I have a program with 2 child processes which has to do the following:我有一个包含 2 个子进程的程序,它必须执行以下操作:
I tried to do it and it works... kinda.我试着去做,它的工作原理......有点。 The problem is, it writes the filtered letters in the desired file, but the program does not stop.
问题是,它将过滤后的字母写入所需的文件,但程序并没有停止。 What am I doing wrong?
我究竟做错了什么?
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>
int parentChildpipeFileDescriptors[2], child1Child2FileDescriptors[2];
void parentProcess()
{
close(child1Child2FileDescriptors[0]);
close(child1Child2FileDescriptors[1]);
close(parentChildpipeFileDescriptors[0]);
int fileDescriptor = open("data.txt", O_RDONLY);
char buffer[8];
int store;
while ((store = read(fileDescriptor, buffer, 8)))
{
write(parentChildpipeFileDescriptors[1], buffer, store);
}
close(fileDescriptor);
close(parentChildpipeFileDescriptors[1]);
}
void child1Process()
{
close(parentChildpipeFileDescriptors[1]);
close(child1Child2FileDescriptors[0]);
char buffer[8];
int store, count = 0;
while ((store = read(parentChildpipeFileDescriptors[0], buffer, 8)))
{
for (int i = 0; i < store; i++)
{
if (buffer[i] >= 'a' && buffer[i] <= 'z')
{
count++;
write(child1Child2FileDescriptors[1], &buffer[i], sizeof(buffer[i]));
}
}
}
printf("CHILD 1 FINISHED FILTERING\n");
close(parentChildpipeFileDescriptors[0]);
close(child1Child2FileDescriptors[1]);
exit(count);
}
void child2Process()
{
close(parentChildpipeFileDescriptors[0]);
close(child1Child2FileDescriptors[1]);
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char *fileName = "stat.txt";
int newFileDescriptor = creat(fileName, mode);
char buffer;
int store;
while ((store = read(child1Child2FileDescriptors[0], &buffer, 1)))
{
write(newFileDescriptor, &buffer, sizeof(buffer));
write(newFileDescriptor, "\n", 1);
}
close(newFileDescriptor);
printf("CHILD 2 FINISHED WRITING'\n");
close(child1Child2FileDescriptors[0]);
close(parentChildpipeFileDescriptors[1]);
exit(444);
}
int main(int argc, char const *argv[])
{
if (pipe(parentChildpipeFileDescriptors) < 0)
{
printf("ERROR CREATING PIPE\n");
exit(-100);
}
if (pipe(child1Child2FileDescriptors) < 0)
{
printf("ERROR CREATING PIPE\n");
exit(-101);
}
pid_t child1PID = fork();
if (child1PID < 0)
{
printf("ERROR CREATING CHILD\n");
exit(-200);
}
if (!child1PID)
{
child1Process();
}
pid_t child2PID = fork();
if (child2PID < 0)
{
printf("ERROR CREATING CHILD\n");
exit(-201);
}
if (!child2PID)
{
child2Process();
}
parentProcess();
int status1, status2;
waitpid(child1PID, &status1, 0);
waitpid(child2PID, &status2, 0);
printf("CHILD 1 TERMINATED WITH EXIT STATUS: %d\n", WEXITSTATUS(status1));
printf("CHILD 2 TERMINATED WITH EXIT STATUS: %d\n", WEXITSTATUS(status2));
return 0;
}
The read loop in child1process will never terminate, because child2 still has the write side of that pipe open. child1process 中的读取循环永远不会终止,因为 child2 仍然打开该管道的写入端。 You need to execute:
你需要执行:
close(parentChildpipeFileDescriptors[1]);
before you enter the read loop.在进入读取循环之前。 The general rule is that if a process isn't going to use a file descriptor, it should close it immediately.
一般规则是,如果一个进程不打算使用文件描述符,它应该立即关闭它。
your while ((store = read(parentChildpipeFileDescriptors[0], buffer, 8)))
loop is never gonna end.你的
while ((store = read(parentChildpipeFileDescriptors[0], buffer, 8)))
循环永远不会结束。
The parent needs to say to the child that there is no more data coming and it shall not do another read.父母需要告诉孩子没有更多的数据来了,它不会再读了。 You can do this by sending a special byte.
您可以通过发送一个特殊字节来做到这一点。
Example :例子 :
in the parent:在父母中:
char endByte = 0x1;
write(parentChildpipeFileDescriptors[1], &endByte, 1);
//then close
in the while loop of the child :在孩子的while循环中:
if(buffer[i] == 0x1){
printf("CHILD 1 FINISHED FILTERING\n");
fflush(stdout);
close(parentChildpipeFileDescriptors[0]);
close(child1Child2FileDescriptors[1]);
exit(count);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.