C 分叉时错误的数据输出
我的c程序有问题 我在模拟F1的训练。 没有福克,我有相关数据。 但当我分叉得到22个进程时,我得到了无关的数据 例如:C 分叉时错误的数据输出,c,C,我的c程序有问题 我在模拟F1的训练。 没有福克,我有相关数据。 但当我分叉得到22个进程时,我得到了无关的数据 例如: Pilote编号不正确 不切实际的最佳时间(0分钟0秒0毫秒) 以下是“制造比赛”(不带叉子)的程序: 现在是“制造比赛”(现在使用叉子)的程序。 只有for(…;j
- Pilote编号不正确李>
- 不切实际的最佳时间(0分钟0秒0毫秒)
只有for(…;j
pid_t tabPID[MAX_PILOTES];
int j;
for (j = 0; j < MAX_PILOTES; j++) { /* Creation of 22 processes */
tabPID[j] = fork();
if (tabPID[j] == -1) { // Error
printf("Erreur lors du fork()\n");
return 0;
}
if (tabPID[j] == 0) { // Fils
pilotesTab[j].pilote_id = pilotes_numbers[j]; // Init pilote id
//printf("PILOTE ID: %d\n", pilotesTab[j].pilote_id); // OK
//waitpid(tabPID[j], NULL, 0);
run(&pilotesTab[j], "Practices");
exit(0);
} else {
/* Nothing */
}
} /* End of the 22 processes */
最后,显示结果的代码(在另一个.c文件中):
我不认为这是一个竞争的问题。是吗?好吧,所以我不是
fork
专家,但这是我的诊断
当您使用fork时,整个环境都将被克隆
这意味着无论您在子进程中做什么,都不会影响父进程中发生的事情。在这里,您应该打印来自子进程的数据,因为您的将引导
父进程中的tab
完全不受种族影响
您的打印是“错误的”,因为您打印的所有值都没有初始化。您实际上是在打印声明表时堆栈中的任何内容
此外,由于tabPID[j]==0
您正在调用waitpid(0,0,0)
引用那个男人的话,wait(2)
因为这是在子进程中调用的,所以您正在等待来自您的子进程的子进程的信号,我相信这些信号是不存在的。
您可能不想在else
在一个答案中编辑最近的评论(针对其他用户):
- 访问分叉程序中数据的一个好方法是设置共享内存(使用
)shmget
- fork提出的第二个问题是随机生成(在中引发),因为srand只在父进程中调用,所以所有子进程都有相同的随机种子,因此结果相同。答案是:调用
srand(time(NULL)^(getpid())你可能想把你的评论翻译成英语给我们这些不会说法语的人。问题是当所有的领航员都做了练习时,我必须展示结果,这意味着在循环之外,所以如果我按照你的建议做,并试着打印来自子进程的数据,我只会得到第一个领航员的结果,因为我仍然是在for循环中,程序将执行_showResults()函数在第一次迭代时运行。我错了吗?确实,这意味着不使用
,您可以调整它以仅打印当前数据。另一个选项是不使用fork。可能有一种方法可以从fork程序收集精确的数据,但我不知道任何方法。@Mathieurusseau,当然有一些方法可以让父进程从它的子级收集数据。有很多方法。在程序结构中需要最少更改的方法是设置一个共享内存段(在分叉之前)其中存储了子级必须写入的数据结构。其他备选方案包括:让子级将结果写入文件以供父级读取;让他们通过管道将结果发送回父级;让他们将结果发送到消息队列。还有其他不太可能的。感谢clarification,我应该将其添加到我的答案中,还是您想添加您的答案?好的,我设置了一个共享内存,但现在我有两个其他问题:-我不知道何时何地应该分离并删除SM段。-所有的车都有相同的最佳时间(例如:1m45s930ms)\u showresult
1: voiture n°26: (1m44s239ms) 2: voiture n°11: (1m44s503ms) 3: voiture n°33: (1m44s587ms) 4: voiture n°55: (1m44s672ms) 5: voiture n°20: (1m44s720ms) 6: voiture n°12: (1m44s864ms) 7: voiture n°7: (1m45s87ms) 8: voiture n°77: (1m45s136ms) 9: voiture n°8: (1m45s257ms) 10: voiture n°21: (1m45s383ms) 11: voiture n°14: (1m45s553ms) 12: voiture n°94: (1m45s555ms) 13: voiture n°27: (1m45s702ms) 14: voiture n°30: (1m45s731ms) 15: voiture n°9: (1m45s771ms) 16: voiture n°31: (1m45s792ms) 17: voiture n°3: (1m45s835ms) 18: voiture n°5: (1m45s862ms) 19: voiture n°22: (1m45s907ms) 20: voiture n°44: (1m46s212ms) 21: voiture n°6: (1m46s390ms) 22: voiture n°19: Abandon
pid_t tabPID[MAX_PILOTES]; int j; for (j = 0; j < MAX_PILOTES; j++) { /* Creation of 22 processes */ tabPID[j] = fork(); if (tabPID[j] == -1) { // Error printf("Erreur lors du fork()\n"); return 0; } if (tabPID[j] == 0) { // Fils pilotesTab[j].pilote_id = pilotes_numbers[j]; // Init pilote id //printf("PILOTE ID: %d\n", pilotesTab[j].pilote_id); // OK //waitpid(tabPID[j], NULL, 0); run(&pilotesTab[j], "Practices"); exit(0); } else { /* Nothing */ } } /* End of the 22 processes */
1: voiture n°1: Abandon 2: voiture n°32765: (0m0s0ms) 3: voiture n°32593: Abandon 4: voiture n°888005824: Abandon 5: voiture n°32593: Abandon 6: voiture n°1700966438: Abandon 7: voiture n°4196464: Abandon 8: voiture n°0: (0m0s0ms) 9: voiture n°878665720: Abandon 10: voiture n°16220219: Abandon 11: voiture n°885803424: Abandon 12: voiture n°885789819: Abandon 13: voiture n°46: Abandon 14: voiture n°887994784: (0m32s765ms) 15: voiture n°0: Abandon 16: voiture n°32593: Abandon 17: voiture n°32593: Abandon 18: voiture n°0: Abandon 19: voiture n°0: (13193m41s423ms) 20: voiture n°32765: Abandon 21: voiture n°32765: Abandon 22: voiture n°0: (32546m42s655ms)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/sem.h> #include <time.h> #include <string.h> #include <math.h> #include <semaphore.h> #include "CourseF1.h" #include "ResultCourse.h" #define MAX_PILOTES 22 void showResults(struct Pilote tab[], int nbElems, char* name) { if (strcmp(name, "Race") != 0) { qsort(tab, nbElems, sizeof(Pilote), compareTot); for (int k = 0; k < nbElems; k++) { if (tab[k].hasGivenUpDuringRace || tab[k].best == 3 * 60 * 3600 + 3) { printf("%d: voiture n°%d: Abandon\n", k+1, tab[k].pilote_id); continue; } printf( "%d%s%d%s%d%s%d%s%d%s\n" ,k+1, ": voiture n°", tab[k].pilote_id, ": (", tab[k].best/60000, "m", tab[k].best / 1000 % 60, "s", tab[k].best-(tab[k].best/1000)*1000, "ms)" ); } } else { for (int k = 0; k < nbElems; k++) { qsort(tab, nbElems, sizeof(Pilote), compareBest); if (tab[k].hasGivenUpDuringRace || tab[k].best == 3 * 60 * 3600 + 3) { printf("voiture n°%d: Abandon\n", tab[k].pilote_id); continue; } printf( "%d%s%d%s%d%s%d%s%d%s\n" ,k+1, ": voiture n°", tab[k].pilote_id, ": (", tab[k].totalTime/60000,"m", (tab[k].totalTime/1000)%60,"s", tab[k].totalTime-(tab[k].totalTime/1000)*1000,"ms)" ); } } }
struct Pilote *pilotesTab; // pointer to SM. Instead of a simple array of struct as before pid_t tabPID[MAX_PILOTES]; int shmid = 0; key_t key; /** * Set up shared memory */ // Key generation for shared memory key = ftok(argv[0], 123); // argv[O] => nom du programme lancé, ID (char) // Initialisation of shared memory shmid = shmget(key, MAX_PILOTES * sizeof(Pilote), IPC_CREAT | 0644); if (shmid == -1) { printf("Erreur lors de l'allocation de la shared memory."); return 0; } // Attach the shared memory pilotesTab = shmat(shmid, NULL, 0); /** * Fork (The same code than before) */ int j; for (j = 0; j < MAX_PILOTES; j++) { /* Création des 22 processus */ tabPID[j] = fork(); if (tabPID[j] == -1) { // Erreur printf("Erreur lors du fork()\n"); return 0; } if (tabPID[j] == 0) { // Fils pilotesTab[j].pilote_id = pilotes_numbers[j]; // Initialise le numéro du pilote //printf("PILOTE ID: %d\n", pilotesTab[j].pilote_id); // OK run(&pilotesTab[j], "Practices"); exit(0); } else { waitpid(tabPID[j], NULL, 0); //shmdt(pilotesTab); //shmctl(shmid, IPC_RMID, 0); } } /* Fin des 22 processus */ printf("==================================================== \n"); fillTab(mainRun, pilotesTab, 0, MAX_PILOTES); // Fill the tab (mainRun) with the data from the SM (before sorting because we can't sort SM). showResults(mainRun, MAX_PILOTES, "Practices"); printf("====================================================\n");
1: voiture n°44: (1m44s908ms) 2: voiture n°6: (1m44s908ms) 3: voiture n°5: (1m44s908ms) 4: voiture n°7: (1m44s908ms) 5: voiture n°3: (1m44s908ms) 6: voiture n°33: (1m44s908ms) 7: voiture n°19: (1m44s908ms) 8: voiture n°77: (1m44s908ms) 9: voiture n°11: (1m44s908ms) 10: voiture n°27: (1m44s908ms) 11: voiture n°26: (1m44s908ms) 12: voiture n°55: (1m44s908ms) 13: voiture n°14: (1m44s908ms) 14: voiture n°22: (1m44s908ms) 15: voiture n°9: (1m44s908ms) 16: voiture n°12: (1m44s908ms) 17: voiture n°20: (1m44s908ms) 18: voiture n°30: (1m44s908ms) 19: voiture n°8: (1m44s908ms) 20: voiture n°21: (1m44s908ms) 21: voiture n°31: (1m44s908ms) 22: voiture n°94: (1m44s908ms)
meaning wait for any child process whose process group ID is equal to that of the calling process.