Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序在内部使用fork时迭代过多,而_C_Fork - Fatal编程技术网

C程序在内部使用fork时迭代过多,而

C程序在内部使用fork时迭代过多,而,c,fork,C,Fork,我正在从文件中读取文本行,对于每一行,我都使用几个{fork()-->子进程调用execvp(),父进程调用wait()}来处理它。 在过程结束时,我将结果写入一个文件 问题是:while循环似乎迭代过多,而且写入文件的次数也过多 results.csv文件包含6行,而不是2行(while迭代) 用两行重复一个文本文件,但当我使用printf时,最后一行似乎被读取了两次) 我错过了什么 代码示例为: FILE* results = fopen("results.csv", "w"); if (r

我正在从文件中读取文本行,对于每一行,我都使用几个{fork()-->子进程调用execvp(),父进程调用wait()}来处理它。 在过程结束时,我将结果写入一个文件

问题是:while循环似乎迭代过多,而且写入文件的次数也过多

results.csv文件包含6行,而不是2行(while迭代) 用两行重复一个文本文件,但当我使用printf时,最后一行似乎被读取了两次)

我错过了什么

代码示例为:

FILE* results = fopen("results.csv", "w");
if (results == NULL){
    fclose(fp);
    perror("Failed opening results file");
    exit(-1);
}
fdIn = open(inputPath, O_RDONLY);
if (fdIn < 0){
    perror("Failed opening input file");
    exit(-1);
}
while (fgets(student, sizeof(student), fp) != NULL) {
    // override end line char of unix ('\n') with '\0'
    student[strlen(student)-1] ='\0';
    pid = fork();
    if (pid < 0){
        close(fdIn);
        perror("Failed creating process for executing student's program");
        exit(-1);
    }
    if (pid == 0) {// son process code
        fdOut = open("tempOutput.txt", (O_WRONLY | O_CREAT | O_TRUNC), 0666);
        if (fdOut < 0){
            perror("Failed opening temporary output file");
            exit(-1);
        }
        close(1);
        dup(fdOut);
        close(fdOut);
        close(0);
        dup(fdIn);
        close(fdIn);
        char studProgPath[bufSize];
        strcpy(studProgPath,studentsFolderPath);
        strcat(studProgPath,"/");
        strcat(studProgPath,student);
        strcat(studProgPath,"/");
        strcat(studProgPath,"a.out");
        char * args[] = {"a.out", NULL};
        ret_code = execvp(studProgPath,args);
        if (ret_code == -1){
            perror("Failed executing student program");
            exit(-1);
        }
    }
    waited = wait(&stat);
    if (stat == -1){ // need to grade 0
        printf("%s,0\n",student);
    }else{ // open process to compare the output with the expected
        pid = fork();
        if (pid < 0){
            perror("Failed opening process for comparing outputs");
            exit(-1);
        }
        if(pid == 0) { // son process
            char * args[] = {"comp.exe",outputPath,"tempOutput.txt",NULL};
            ret_code = execvp("comp.exe",args);
            exit(ret_code);
        }
        waited = wait(&stat);
        if (stat == -1) {
            perror("Failed executing comparing program");
            exit(-1);
        } else if (stat == 0 || stat == 1) { // if outputs are not the same
            fprintf(results,"%s,0\n",student);
        } else { // matching outputs grade 100
            fprintf(results,"%s,100, pid: %d\n",student,getpid());
        }
    }
}
FILE*results=fopen(“results.csv”,“w”);
如果(结果==NULL){
fclose(fp);
perror(“打开结果文件失败”);
出口(-1);
}
fdIn=打开(仅输入路径,Ordu);
if(fdIn<0){
perror(“打开输入文件失败”);
出口(-1);
}
while(fgets(student,sizeof(student),fp)!=NULL){
//用'\0'覆盖unix('\n')的结束行字符
学生[strlen(学生)-1]='\0';
pid=fork();
if(pid<0){
关闭(fdIn);
perror(“创建执行学生程序的过程失败”);
出口(-1);
}
如果(pid==0){//son进程代码
fdOut=open(“tempOutput.txt”,(O_WRONLY | O|u CREAT | O|u TRUNC),0666);
如果(fdOut<0){
perror(“打开临时输出文件失败”);
出口(-1);
}
关闭(1);
dup(fdOut);
关闭(fdOut);
关闭(0);
dup(fdIn);
关闭(fdIn);
char studProgPath[bufSize];
strcpy(studProgPath、studentsFolderPath);
strcat(studProgPath,“/”;
strcat(studProgPath,学生);
strcat(studProgPath,“/”;
strcat(studProgPath,“a.out”);
char*args[]={“a.out”,NULL};
ret_code=execvp(studProgPath,args);
如果(返回代码==-1){
perror(“执行学生计划失败”);
出口(-1);
}
}
等待=等待(&stat);
如果(stat==-1){//需要评分0
printf(“%s,0\n”,学生);
}else{//打开进程,将输出与预期值进行比较
pid=fork();
if(pid<0){
perror(“用于比较输出的打开过程失败”);
出口(-1);
}
如果(pid==0){//son进程
char*args[]={“comp.exe”,outputPath,“tempOutput.txt”,NULL};
ret_code=execvp(“comp.exe”,args);
退出(返回代码);
}
等待=等待(&stat);
如果(统计==-1){
perror(“执行比较程序失败”);
出口(-1);
}else如果(stat==0 | | stat==1){//如果输出不相同
fprintf(结果,“%s,0\n”,学生);
}else{//匹配输出100级
fprintf(结果,“%s,100,pid:%d\n”,学生,getpid());
}
}
}

获取三个条目的文件在此处打开:

在函数调用
fork()
之前,以下几行将写入此
结果
文件:

此文件应在fork之前使用
fflush(results)
刷新,否则
results
的缓冲区可能会刷新三次:在父级中,在子级中的两个副本中

另外,
results
student
在调用execvp之前应使用
fclose(results)
student
关闭。如果文件未关闭,则
a.out
可能会操纵
结果
文件。我假设
a.out
是您无法控制的外部代码

while (fgets(student, sizeof(student), fp) != NULL) {
    // override end line char of unix ('\n') with '\0'
    student[strlen(student)-1] ='\0';
    fflush(results); // otherwise each child may flush the same chars
    pid = fork();
    if (pid < 0){
        fclose(results); // otherwise ./a.out might write to this file
        fclose(fp); // better also close it.
        close(fdIn);
while(fgets(学生,sizeof(学生),fp)!=NULL){
//用'\0'覆盖unix('\n')的结束行字符
学生[strlen(学生)-1]='\0';
fflush(results);//否则每个子级可以刷新相同的字符
pid=fork();
if(pid<0){
fclose(results);//否则。/a.out可能会写入此文件
fclose(fp);//最好也关闭它。
关闭(fdIn);

注意,您不需要测试
execvp()
(或任何其他
exec*()
函数)的返回值。如果函数成功,则不返回;如果返回,则失败。
a.out
程序对其标准输入做了什么?将文件输入重定向到成为
a.out
进程的标准输入有点奇怪。如果
comp.exe
进程失败,则不会打印错误。untl你知道哪里出了问题,应该把它打印出来——甚至在你知道发生了什么之后。你也应该把fclose(fp)和fclose(results)打印出来在第一次执行之前,VP.还应该在每个fork之前刷新结果,或者在fprintf之后和下一个fork之前刷新结果fork@JonathanLefflera.out正在从stdin读取数据,所以我将其重定向到我的输入文件。@ovedmani我的意思是,在fork之前刷新它之后,您应该只在子对象中关闭它。在子对象中关闭它不会关闭它父母
} else if (stat == 0 || stat == 1) { // if outputs are not the same
  fprintf(results,"%s,0\n",student); 
} else { // matching outputs grade 100 
  fprintf(results,"%s,100, pid: %d\n",student,getpid()); 
}
while (fgets(student, sizeof(student), fp) != NULL) {
    // override end line char of unix ('\n') with '\0'
    student[strlen(student)-1] ='\0';
    fflush(results); // otherwise each child may flush the same chars
    pid = fork();
    if (pid < 0){
        fclose(results); // otherwise ./a.out might write to this file
        fclose(fp); // better also close it.
        close(fdIn);