对于这篇文章的篇幅感到抱歉......我遇到了很多问题。在前面,我会说我是学生,而我的教授是一个毫无价值的资源。因此,我想要做的就是使用生产者fork,然后父生产者将计算文件中的一些内容并将两个int发送给消费者,这是由子进程启动的。我已经测试了所有东西,fork和文件的东西都可以工作,我在各处都有printf语句,所以我知道正在做什么以及代码在哪里。
当我添加
时if (pipe(pipefd) == -1) {
perror("pipe");
}
它导致我的父母终止。它达到“父管打开”但随后它就死了。我用$ ps检查它是否只是悬挂,但它不存在;它就死了。如果我把那个片段拿出来,它会运行到最后,但我认为如果那个代码不存在,那么它实际上并不知道pipefd是一个管道......对吗?
我在这个网站上进行了搜索并找到了另一个例子,并按照他所做的和答案,我的拒绝工作。我很确定这是一个非常容易解决的问题,但我已经没有尝试过的想法了:(
我真的不想发布我的所有代码,因为它将是一个巨大的文本墙,但我不想意外地删除一些结果也很重要。
producer.c
#include <stdio.h> /* printf, stderr, fprintf */
#include <sys/types.h> /* pid_t */
#include <unistd.h> /* _exit, fork, execl */
#include <stdlib.h> /* exit */
#include <errno.h> /* errno */
#include <string.h> /* strlen */
#include <sys/wait.h> /* wait */
#define SLEEP_TIME 8
int main (int argc, char *argv[]){
//PID
pid_t local_pid;
local_pid = fork();
//Logic to determine if the process running is the parent or the child
if (local_pid == -1) {
/* Error:
* When fork() returns -1, an error happened
* (for example, number of processes reached the limit).
*/
fprintf(stderr, "can't fork, error %d\n", errno);
exit(EXIT_FAILURE);
} else if (local_pid == 0) {
//Child specific code
int child;
char *temp[] = {NULL};
printf("Child PID found\n");
child = execv("./consumer", temp);
_exit(0);
} else {
//Parent specific code
printf("Parent running\n");
//open file
FILE * randStrings;
randStrings = fopen("randStrings.txt", "r");
int file_length;
int num_of_e = 0;
int c; //using this as a char
//until eof
while (feof(randStrings) == 0) {
c = fgetc(randStrings);
//calculate length of file
file_length++;
//count e chars
if (c == 'e') {
num_of_e++;
}
}
//close file
fclose(randStrings);
//send bundle to child
int a[2];
a[0] = num_of_e;
a[1] = file_length;
printf("num of e = %i\n", a[0]);
printf("len = %i\n", a[1]);
//set up parent pipe
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
printf("x\n");
}
printf("parent pipe open\n");
close(pipefd[0]); //close the read end
write(pipefd[1], &a[0], sizeof(int));
write(pipefd[1], &a[1], sizeof(int));
close(pipefd[1]);
printf("parent pipe closed\n");
//wait for child to finish running
wait(NULL);
printf("parent out\n");
//terminate
}
}
和consumer.c
#include <stdio.h> /* printf, stderr, fprintf */
#include <sys/types.h> /* pid_t */
#include <unistd.h> /* _exit, fork, execl */
#include <stdlib.h> /* exit */
#include <errno.h> /* errno */
#define SLEEP_TIME 5
int main (int argc, char *argv[]){
sleep(SLEEP_TIME);
printf("Child program launched\n");
//receive bundle
int pipefd[2];
int buf[2];
if (pipe(pipefd) == -1) {
perror("pipe");
printf("child x\n");
}
close(pipefd[1]); //child closes write end
buf[0] = 0;
buf[1] = 0;
/*int i = 0; // i dont like this
while (read(pipefd[0], &buf[i], sizeof(int)) > 0) {
i++;
}*/
printf("child reading pipe\n");
read(pipefd[0], &buf[0], sizeof(int));
read(pipefd[0], &buf[1], sizeof(int));
close(pipefd[0]);
//buf should have the stuff in it
int num_of_e = buf[0];
int file_length = buf[1];
printf("child num of e = %i\n", num_of_e);
printf("child len = %i\n", file_length);
//open file
FILE * resultStrings;
resultStrings = fopen("resultStrings.txt", "w");
for (int i = 0; i < num_of_e; i++) {
//write num_of_e e chars
fputc('e', resultStrings);
}
//or if no e chars, write - chars
if (num_of_e == 0) {
for (int i = 0; i < file_length; i++) {
//write file_length '-' chars
fputc('-', resultStrings);
}
}
//close file
fclose(resultStrings);
printf("child out\n");
}
如果你仍然在这里,你应该感谢你,因为它的长度。
答案 0 :(得分:2)
你做错了。整个机制起作用,因为子进程继承了父进程的打开文件描述符。
它应该是这样的:
pipe(pipefd)
fork()
pipefd[0]
)pipefd[1]
)pipefd[1]
)pipefd[0]
)或调用exec
您正在父进程和子进程中打开不同的管道(在fork
之后。)它需要在fork
之前发生。
既然你是exec
,那么新进程需要知道只读管道。有几种方法可以做到这一点:
pipefd[0]
)dup2(1, fd)
它是新执行过程的标准