【发布时间】:2019-12-10 16:33:59
【问题描述】:
我有一个 C 程序(我们称之为“progam1”)以及 3 个输入文件(比如"in1.txt", "in2.txt", in3.txt")和 3 个初始为空的输出文件("out1, "out2","out3"),它们表示对各种多边形的操作。
从progam1::main,我调用fork 3次,在每个子进程中,我使用dup2将标准输入/输出重定向到输入/输出文件之一,然后调用execve("helper",. ..),其中helper 是另一个解析输入、进行一些计算并打印输出的 C 程序。
我似乎无法解决的问题是,每当我多次调用execve(helper,...) 时,第一次调用都可以正常工作(输入/输出如我所料),但随后出现问题;我似乎要么最终得到一个文件helper.exe.stackdump,要么系统不断地将相同的数据打印到输出文件,或者其他一些意想不到的结果。
作为一个实验,我编写了另一个 C 程序 - "simpleWrite.c",它只是将输入复制到输出。我正在使用 cygwin 运行所有这些程序。
如果我将
simpleWrite传递给program1中的所有3 个execve调用, 然后一切正常(所有 3 个重定向输入都复制到 3 个输出文件符合预期)。如果我将
simpleWrite传递给一个孩子(比如第三个孩子)并从终端运行./program1,那么系统完成并且第一个和第三个子进程按预期工作。第二个输出是空的,我最终在我的目录中有一个文件"helper.exe.stackdump"。如果我只将
helper传递给所有 3 个子 exec 并从终端运行./program1,那么系统永远不会完成。当我检查输出文件时,一个输出符合预期,一个输出为空,一个输出无限多次打印正确的数据。
谁能解释可能发生的事情!?或者解释什么是 stackdump 文件以及如何检查它,或者建议我如何解决这个问题?
以下是我的代码的大致概念:
//program1.c
#define INPUT1 "in1.txt"
#definte OUTPUT1 "out1.txt"
// same for rest of input/output files
char* my_argv[2];
int main(int argc, char* argv[])
{
char prog_name[20] = "helper";
char prog_name2[20] = "simpleWrite";
my_argv[0] = "helper";
my_argv[1] = NULL;
pid_t pid1, pid2, pid3, pid;
int status;
if ((pid1 = fork()) < 0) {
printf("Failed to fork process 1\n");
exit(1);
}
else if (pid1 == 0)
{
// redirection here for the child only
int fd_in = open_file_desc(INPUT1);
int fd_out = open_file_desc(OUTPUT1);
dup2(fd_in, 0);
dup2(fd_out,1);
close(fd_in);
close(fd_out);
execve(prog_name, my_argv, NULL);
//alternately, execve(prog_name2, my_argv, NULL);
}
if ((pid2 = fork()) < 0) {
//...
}
else if (pid2 == 0)
{
int fd_in2 = open_file_desc(INPUT2);
int fd_out2 = open_file_desc(OUTPUT2);
...// same idea as above
}
// likewise for pid3
...
//back in parent process
pid = wait(&status);
printf("\n***Parent detects process %d was terminated ***\n", pid);
pid = wait(&status);
printf("\n*** Parent detects process %d was terminated ***\n", pid);
pid = wait(&status);
printf("\n*** Parent detects process %d was terminated ***\n", pid);
// dup2(sav_stdin, 0);
// dup2(sav_stdout, 1);
// dup2(sav_stderr, 2);
exit(0);
}
//helper.c
enum POLYGON { HEXAGON = 6, HEPTAGON = 7, OCTAGON = 8 };
struct point {
short *X, *Y;
};
struct polygon
{
enum POLYGON type;
struct point points;
};
struct Node {
struct polygon* poly;
struct Node* next;
};
struct Node *HEAD = NULL;
struct Node *TAIL = NULL;
int main()
{
int lastCommand = 0, polygonscreated =0, newPolygonBit;
//other variables needed for parsing/calculations
while (!lastCommand)
{
scanf("%llx", &input);
//parsing stuff
if (newPolygonBit == 1)
{
polygonscreated = polygonscreated+1;
scanf("%llx", &setOfPoints1);
scanf("%llx", &setOfPoints2);
struct polygon* polyptr = createPolygon(polyType, setOfPoints1, setOfPoints2);
func[ADD_POLYGON](polyptr);
}
lastCommand = input & 1;
}
freeList(HEAD);
printf("Created %d polygons", polygonscreated);
return polygonscreated;
}
//simpleWrite.c
int main()
{
char c;
while( read(0, &c, 1) > 0){
write(1, &c,1);
}
return 0;
}
【问题讨论】:
标签: c operating-system fork exec io-redirection