当我将标准输出重定向到文本文件时,我的程序输出不一致。那是./main
和./main > out.txt
有不同的输出。
执行程序可以最好地理解问题。这是我的口头描述(如果你想阅读它)。
我用./main
执行的行为是我想要的。重定向输出时,我在程序中使用的计数器似乎被重置,这是不可取的。我添加了一些额外的打印语句,以帮助使其更清晰。
我的目标是:生成五个子进程,每个进程写入一个缓冲区(由管道支持)。然后在主要打印每个子进程的缓冲区。
这是在不重定向输出的情况下发生的事情。当我重定向输出时,我得到一个递归/级联结果。第一个进程的结果是正确的,但每个后续进程都会打印在它之前返回的进程。
我使用了valgrind并且没有发现任何内存泄漏。我注意到有超过三个FD打开了,我认为这可能表明文件描述符泄漏。
SO不允许使用网址缩短程序
单独生成;相当于但不同于Google doc图像。
Fork Instance: 0
Child Process (30869) Terminating...
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30869
The value of i is: 0
Fork Instance: 1
Child Process (30870) Terminating...
Exit Status: Normal Value: 0
1 5 buf: Message left from: 30870
The value of i is: 1
Fork Instance: 2
Child Process (30871) Terminating...
Exit Status: Normal Value: 0
2 7 buf: Message left from: 30871
The value of i is: 2
Fork Instance: 3
Child Process (30872) Terminating...
Exit Status: Normal Value: 0
3 9 buf: Message left from: 30872
The value of i is: 3
Fork Instance: 4
Child Process (30873) Terminating...
Exit Status: Normal Value: 0
4 11 buf: Message left from: 30873
The value of i is: 4
Parent Process (30868) Terminating...
单独生成;相当于但不同于Google doc图像。
Fork Instance: 0
Child Process (30791) Terminating...
Fork Instance: 0
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30791
The value of i is: 0
Fork Instance: 1
Child Process (30792) Terminating...
Fork Instance: 0
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30791
The value of i is: 0
Fork Instance: 1
Exit Status: Normal Value: 0
1 5 buf: Message left from: 30792
The value of i is: 1
Fork Instance: 2
Child Process (30793) Terminating...
Fork Instance: 0
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30791
The value of i is: 0
Fork Instance: 1
Exit Status: Normal Value: 0
1 5 buf: Message left from: 30792
The value of i is: 1
Fork Instance: 2
Exit Status: Normal Value: 0
2 7 buf: Message left from: 30793
The value of i is: 2
Fork Instance: 3
Child Process (30794) Terminating...
Fork Instance: 0
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30791
The value of i is: 0
Fork Instance: 1
Exit Status: Normal Value: 0
1 5 buf: Message left from: 30792
The value of i is: 1
Fork Instance: 2
Exit Status: Normal Value: 0
2 7 buf: Message left from: 30793
The value of i is: 2
Fork Instance: 3
Exit Status: Normal Value: 0
3 9 buf: Message left from: 30794
The value of i is: 3
Fork Instance: 4
Child Process (30795) Terminating...
Fork Instance: 0
Exit Status: Normal Value: 0
0 3 buf: Message left from: 30791
The value of i is: 0
Fork Instance: 1
Exit Status: Normal Value: 0
1 5 buf: Message left from: 30792
The value of i is: 1
Fork Instance: 2
Exit Status: Normal Value: 0
2 7 buf: Message left from: 30793
The value of i is: 2
Fork Instance: 3
Exit Status: Normal Value: 0
3 9 buf: Message left from: 30794
The value of i is: 3
Fork Instance: 4
Exit Status: Normal Value: 0
4 11 buf: Message left from: 30795
The value of i is: 4
Parent Process (30789) Terminating...
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_NUM 5
int main ()
{
char buf [100];
memset(buf, 0, sizeof buf);
int ret;
pid_t pid;
int mypipefd [MAX_NUM][2];
for (int i = 0; i < MAX_NUM; i++)
{
ret = pipe(mypipefd[i]);
if (ret == -1)
{
perror("\nPipe Error... Exiting\n");
exit(1);
}
}
for (int i = 0; i < MAX_NUM; i++)
{
printf ("\nFork Instance:\t%d\n", i); //Removing trailing \n changes output
pid = fork();
if ( pid == -1)
{
perror("\nFork Error... Exiting\n");
exit(1);
}
else if (pid == 0)
{
int dupRes = dup2(0, mypipefd[i][0]);
if (dupRes == -1)
{
perror("\nDup2 Error... Exiting\n");
exit(1);
}
close(mypipefd[i][0]); // Redundant?
pid_t childID = getpid();
char testString [50];
sprintf(testString, "%s%ld", "Message left from: ", (long) childID );
ssize_t writeResult = write(mypipefd[i][1], testString, strlen(testString));
if (writeResult == -1)
{
perror("\nWriting Error... Exiting\n");
exit(1);
}
printf("\nChild Process (%ld) Terminating...\n", (long) childID);
return 0;
}
else
{
//Credit to: Paul Griffiths [http://stackoverflow.com/questions/35471521/waitstatus-wexitstatusstatus-always-returns-0]
int status;
if ( waitpid( pid, &status, 0 ) != -1 )
{
if (WIFEXITED(status))
{
int retval = WEXITSTATUS(status);
printf("\nExit Status: Normal\tValue: %d",retval);
}
else if (WIFSIGNALED(status))
{
int retSig = WTERMSIG(status);
printf("\nExit Status:\tSignal Exit\tValue:\t%d",retSig);
}
else if (WIFSTOPPED(status))
{
int retSig = WSTOPSIG(status);
printf("\nExit Status:\tStop\tValue:\t%d",retSig);
}
else
{
perror("\nExit Status:WAIT PID UNKNOWN INSTANCE... Terminating\n");
exit(1);
}
}
close(mypipefd[i][1]);
ssize_t readResult = read(mypipefd[i][0], buf, 100);
if (readResult == -1)
{
perror("\nRead Error... Exiting\n");
exit(1);
}
printf("\n%d %d buf:\t%s\n", i, mypipefd[i][0], buf);
memset(buf, 0, sizeof buf);
printf("\nThe value of i is:\t%d\n",i);
}
}
pid_t parentID = getpid();
printf("\nParent Process (%ld) Terminating...\n", (long) parentID);
return 0;
}