英文:
Problems with fgets function while multiple processes are running
问题
我不确定为什么,但是fgets这行代码被跳过了,当我将在子进程1.1中运行的代码粘贴到一个单独的文件中时,它正常工作。我已经读到可能是输入缓冲区的问题,但我不知道如何解决这个问题。
英文:
I'm not sure why but the fgets line is just skipped, when i paste the code that is run in child process 1.1 into a seperate file it works fine. I have read that it maybe an issue with the input buffer but I have no clue how to address this issue here
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>
int main() {
int pid1, pid2, pid3, pid11, pid12, pid21, pid22;
int n;
char text[100];
char input[100];
pid1 = fork();
if (pid1 == 0) {
// Child process 1
if (creat("p1.txt", 0700) < 0) {
printf("Error creating p1.txt\n ");
}
if (creat("p2.txt", 0700) < 0) {
printf("Error creating p2.txt\n ");
}
pid11 = fork();
if (pid11 == 0) {
// Child process 1.1
printf("Enter your input: ");
fgets(input, 100, stdin);
printf("Your input: %s", input);
} else {
pid12 = fork();
if (pid12 == 0) {
// Child process 1.2
}
}
wait(NULL);
} else {
pid2 = fork();
if (pid2 == 0) {
// Child process 2
pid21 = fork();
if (pid21 == 0) {
// Child process 2.1
} else {
pid22 = fork();
if (pid22 == 0) {
// Child process 2.2
}
}
wait(NULL); // Wait for child process 2.1 to finish
} else {
pid3 = fork();
if (pid3 == 0) {
// Child process 3
}
}
}
wait(NULL); // Wait for all child processes to finish
return 0;
}
I have tried also using printf but it doesn't work as well (I need to use fgets because my teacher said so). (The code isn't finished)
答案1
得分: 1
在wait()
函数中存在一个问题(还有其他问题)。
与你想的不同,它只等待一个子进程。所以整个程序在你能输入任何内容之前就提前结束了。
如果你将 wait(NULL);
替换为 for(;;)wait(NULL);
,fgets
将按预期工作。(请注意,添加一个无限循环只是为了演示;你应该在不同的地方添加多个 wait()
来分别等待每个子进程。)
英文:
One of the problems (there are several) is in the wait() function.
Contrary to what you think, it only waits for one child at a time. So the whole program finishes early before you can enter anything.
if you replace wait(NULL);
by for(;;)wait(NULL);
the fgets will work as expected. (Note that adding an infinite loop is just for the demo; you should add several wait() at different places to wait for each child separately instead)
答案2
得分: 1
J.P. Tosoni正确命名了失败的原因,但没有解释它们之间的相互关系,所以我来尝试一下。
实际上,并不是仅仅跳过了fgets行,而是底层的read
执行时发生了错误;如果我们之后检查errno
,会看到EIO
:
> I/O错误。例如,当进程处于后台进程组中,尝试从其控制终端读取数据,要么它正在忽略或阻塞SIGTTIN,要么其进程组变成了孤儿进程组时,会发生这种情况。也可能发生在从磁盘或磁带读取时发生低级I/O错误的情况下。
在这种情况下,当父进程退出时,其进程组(包括其子进程和孙子进程)会变成孤儿进程组。
1: https://www.gnu.org/software/libc/manual/html_node/Orphaned-Process-Groups.html
英文:
J.P. Tosoni correctly named the cause of the failure, but didn't explain the interrelations, so I'll try.
It's actually not that the fgets line is just skipped, but rather the underlying read
is executed with an error; if we inspect errno
afterwards, we see EIO
:
> I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-level
I/O error while reading from a disk or tape.
In the case at hand when the parent process exits, its process group (consisting of its children and grandchildren) becomes orphaned.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论