创建两个子进程以根据父进程的输入写入单独的文件
我需要编写一个创建两个子进程的程序。这些进程的父进程将从用户处获取数字,第一个子进程会将输入的奇数写入名为 odd.txt 的文件,而第二个子进程会将偶数写入名为 Even.txt 的文件。 (我必须利用系统调用来处理文件,而不是 fopen 等)
当用户输入 -1 时程序停止。
我的下面的代码有很多问题。虽然它允许我输入数字并在输入 -1 时停止,但文件的输出是乱码。在此处显示的示例输出中,子进程仅打印输入的第一个数字(如果是奇数,则仅打印子进程 1,反之亦然)。
我也遇到了输入 0 时整个程序中断的问题,如果我尝试在 0 之后输入数字,则会出现分段错误和管道损坏。我猜这一定与 hasData 有关,但不确定如何。
我真的很茫然,不知道它是什么是我做错了。任何帮助非常感谢!这是一道考试题,我没能做完。
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
int p1 = fork();
// Create a pipe
int fd[2];
if (pipe(fd) == -1){
printf("Could not create a pipe.");
return 1;
}
if (p1 > 0){
// Parent
int p2 = fork();
if (p2 > 0){
// Parent
close(fd[0]);
int hasData;
int num;
do
{ printf("Enter a num: ");
scanf("%d", &num);
if (num == -1){
hasData = 0;
write(fd[1], &hasData, sizeof(int));
printf("Thanks for your numbers!");
close(fd[1]);
exit(0);
}
hasData = 1;
write(fd[1], &hasData, sizeof(int));
write(fd[1], &num, sizeof(num));
} while (num!= -1);
}
else if (p2 == 0){
// Second child
sleep(1);
close(fd[1]);
int hasData = 0;
int num2;
read(fd[0], &hasData, sizeof(int));
read(fd[0], &num2, sizeof(int));
int even_fd = open("even.txt", O_WRONLY | O_CREAT);
while (hasData){
if (num2 % 2 == 0){
printf("(from child 2) %d ", num2);
write(even_fd, &num2, sizeof(int));
}
read(fd[0], &hasData, sizeof(int));
}
close(even_fd);
close(fd[0]);
}
} else if (p1 == 0){
// First child
sleep(1);
close(fd[1]);
int hasData = 0;
int num1;
read(fd[0], &hasData, sizeof(int));
read(fd[0], &num1, sizeof(int));
int odd_fd = open("odd.txt", O_WRONLY | O_CREAT);
while (hasData){
if (num1 % 2 != 0){
printf("\n(from child 1) %d ", num1);
write(odd_fd, &num1, sizeof(int));
}
read(fd[0], &hasData, sizeof(int));
}
close(odd_fd);
close(fd[0]);
}
return 0;
}
根据评论的建议编辑代码(尽管仍然不起作用,但 0 输入现在可以正常工作,摆脱了 hasData)
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
// Create a pipe
int pipe1[2];
if (pipe(pipe1) == -1){
printf("Could not create a pipe.");
return 1;
}
int p1 = fork();
if (p1 > 0){
// Parent
int pipe2[2];
if (pipe(pipe2) == -1){
printf("Could not create a pipe.");
return 2;
}
int p2 = fork();
if (p2 > 0){
// Parent
close(pipe1[0]);
close(pipe2[0]);
int num;
do
{ printf("Enter a num: ");
scanf("%d", &num);
if (num == -1){
write(pipe1[1], &num, sizeof(int));
write(pipe2[1], &num, sizeof(int));
printf("\nThanks for your numbers!\n");
close(pipe1[1]);
close(pipe2[1]);
exit(0);
}
if(num%2 != 0){
// odd number
write(pipe1[1], &num, sizeof(num));
} else {
// even number
write(pipe2[1], &num, sizeof(num));
}
} while (num!= -1);
}
else if (p2 == 0){
// Second child
close(pipe2[1]);
close(pipe1[0]);
close(pipe1[1]);
int num2;
read(pipe2[0], &num2, sizeof(int));
int even_fd = open("even.txt", O_WRONLY | O_CREAT);
while (num2 != -1){
printf("\n(from child 2) %d\n", num2);
write(even_fd, &num2, sizeof(int));
read(pipe2[0], &num2, sizeof(int));
}
close(even_fd);
close(pipe2[0]);
}
} else if (p1 == 0){
// First child
close(pipe1[1]);
int num1;
read(pipe1[0], &num1, sizeof(int));
int odd_fd = open("odd.txt", O_WRONLY | O_CREAT);
while (num1 != -1){
printf("\n(from child 1) %d\n", num1);
write(odd_fd, &num1, sizeof(int));
read(pipe1[0], &num1, sizeof(int));
}
close(odd_fd);
close(pipe1[0]);
}
return 0;
}
I need to write a program which creates two child processes. The parent of these processes will take in numbers from the user, and the first child will write the odd numbers input to a file called odd.txt while the second child will write the even numbers to a file called even.txt. (I have to make use of system calls to work with the files and not fopen etc)
The program stops when the user inputs -1.
I'm having many issues with my code below. While it allows me to input numbers and stops when -1 is entered, the output to the files is gibberish. In the sample output shown here, the child process only prints the first number entered (if it was odd, only child 1 prints and vice-versa).
I also have the problem that is 0 is entered, the whole program breaks, with segmentation faults and broken pipes if I try to input numbers after the 0. I'm guessing this somehow must have to do with hasData, but not sure how.
entering 0 as a value breaks things
I'm really at a loss here, not sure what it is that I am doing wrong. Any help much appreciated thanks! This was a question for an exam which I did not manage to get to work.
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
int p1 = fork();
// Create a pipe
int fd[2];
if (pipe(fd) == -1){
printf("Could not create a pipe.");
return 1;
}
if (p1 > 0){
// Parent
int p2 = fork();
if (p2 > 0){
// Parent
close(fd[0]);
int hasData;
int num;
do
{ printf("Enter a num: ");
scanf("%d", &num);
if (num == -1){
hasData = 0;
write(fd[1], &hasData, sizeof(int));
printf("Thanks for your numbers!");
close(fd[1]);
exit(0);
}
hasData = 1;
write(fd[1], &hasData, sizeof(int));
write(fd[1], &num, sizeof(num));
} while (num!= -1);
}
else if (p2 == 0){
// Second child
sleep(1);
close(fd[1]);
int hasData = 0;
int num2;
read(fd[0], &hasData, sizeof(int));
read(fd[0], &num2, sizeof(int));
int even_fd = open("even.txt", O_WRONLY | O_CREAT);
while (hasData){
if (num2 % 2 == 0){
printf("(from child 2) %d ", num2);
write(even_fd, &num2, sizeof(int));
}
read(fd[0], &hasData, sizeof(int));
}
close(even_fd);
close(fd[0]);
}
} else if (p1 == 0){
// First child
sleep(1);
close(fd[1]);
int hasData = 0;
int num1;
read(fd[0], &hasData, sizeof(int));
read(fd[0], &num1, sizeof(int));
int odd_fd = open("odd.txt", O_WRONLY | O_CREAT);
while (hasData){
if (num1 % 2 != 0){
printf("\n(from child 1) %d ", num1);
write(odd_fd, &num1, sizeof(int));
}
read(fd[0], &hasData, sizeof(int));
}
close(odd_fd);
close(fd[0]);
}
return 0;
}
Edited code following advice from comments (still doesn't work though, but 0 input works fine now, got rid of hasData)
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include<fcntl.h>
int main(int argc, char const *argv[])
{
// Create a pipe
int pipe1[2];
if (pipe(pipe1) == -1){
printf("Could not create a pipe.");
return 1;
}
int p1 = fork();
if (p1 > 0){
// Parent
int pipe2[2];
if (pipe(pipe2) == -1){
printf("Could not create a pipe.");
return 2;
}
int p2 = fork();
if (p2 > 0){
// Parent
close(pipe1[0]);
close(pipe2[0]);
int num;
do
{ printf("Enter a num: ");
scanf("%d", &num);
if (num == -1){
write(pipe1[1], &num, sizeof(int));
write(pipe2[1], &num, sizeof(int));
printf("\nThanks for your numbers!\n");
close(pipe1[1]);
close(pipe2[1]);
exit(0);
}
if(num%2 != 0){
// odd number
write(pipe1[1], &num, sizeof(num));
} else {
// even number
write(pipe2[1], &num, sizeof(num));
}
} while (num!= -1);
}
else if (p2 == 0){
// Second child
close(pipe2[1]);
close(pipe1[0]);
close(pipe1[1]);
int num2;
read(pipe2[0], &num2, sizeof(int));
int even_fd = open("even.txt", O_WRONLY | O_CREAT);
while (num2 != -1){
printf("\n(from child 2) %d\n", num2);
write(even_fd, &num2, sizeof(int));
read(pipe2[0], &num2, sizeof(int));
}
close(even_fd);
close(pipe2[0]);
}
} else if (p1 == 0){
// First child
close(pipe1[1]);
int num1;
read(pipe1[0], &num1, sizeof(int));
int odd_fd = open("odd.txt", O_WRONLY | O_CREAT);
while (num1 != -1){
printf("\n(from child 1) %d\n", num1);
write(odd_fd, &num1, sizeof(int));
read(pipe1[0], &num1, sizeof(int));
}
close(odd_fd);
close(pipe1[0]);
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我从你的代码中得出的代码。这对我有用。我也摆脱了
hasData
。这两个子进程基本上是对称的——我花了很长时间才发现我引入的一个不对称性。一个“主要”更改是调用输出文件odd.bin
和even.bin
,因为它们包含二进制数据,而不是文本(因此名称为odd.txt
和even.txt
非常不合适)。使用标准 I/O(fopen()
、fprintf()
、fclose()
)将它们修改为文本文件将是简单而明智的。 )来写数字。另一个重要的变化是,如果输入是终端,它只会提示“Enter a num:
”——当从管道或数据文件驱动时,这会更干净。有很多诊断输出 - 部分原因是我试图找出我提到的那个令人讨厌的不对称性(这是
==
与!=
的情况,正如它所发生的那样) )。父级中的信号处理也有助于跟踪。我使用随机数生成器生成一系列范围在 -1 到 100 之间的数字;它使用我选择的种子在条目 63 处生成 -1:
我得到的运行之一(源代码:
pipe67.c
;程序:pipe67
;数据文件:pipe67.in
)是:我还编写了一个“dumper”程序(源代码
dump97.c
编译为dump97
- 编译类似于pipe67
编译)验证两个输出文件:运行这些文件给出:
一切似乎都是一致的。
Here's the code I derived from yours. It works for me. I too got rid of
hasData
. The two child processes are largely symmetric — it took me a depressingly long time to spot the one piece of asymmetry I introduced. One 'major' change is to call the output filesodd.bin
andeven.bin
since they contain binary data, not text (so the namesodd.txt
andeven.txt
are singularly inappropriate). It would be easy and sensible to revise them to text files using standard I/O (fopen()
,fprintf()
,fclose()
) to write the numbers. Another significant change is that it only prompts for "Enter a num:
" if the input is a terminal — this is cleaner when driven from a pipe or data file.There's a lot of diagnostic output — partly as I was trying to track down that annoying asymmetry that I mentioned (it was a case of
==
vs!=
, as it happens). The signal handling in the parent is there also to help with the tracking.I used a random number generator to generate a series of numbers in the range -1 to 100; it generated -1 at entry 63 with the seed I chose:
One of the runs I got (source code:
pipe67.c
; program:pipe67
; data file:pipe67.in
) was:I also wrote a 'dumper' program (source
dump97.c
compiled todump97
— compilation analogous to thepipe67
compilation) to validate the two output files:Running those gave:
That all seems consistent.