C 分叉时错误的数据输出

C 分叉时错误的数据输出,c,C,我的c程序有问题 我在模拟F1的训练。 没有福克,我有相关数据。 但当我分叉得到22个进程时,我得到了无关的数据 例如: Pilote编号不正确 不切实际的最佳时间(0分钟0秒0毫秒) 以下是“制造比赛”(不带叉子)的程序: 现在是“制造比赛”(现在使用叉子)的程序。 只有for(…;j

我的c程序有问题

我在模拟F1的训练。 没有福克,我有相关数据。 但当我分叉得到22个进程时,我得到了无关的数据

例如:

  • 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()函数在第一次迭代时运行。我错了吗?确实,这意味着不使用
    \u showresult
    ,您可以调整它以仅打印当前数据。另一个选项是不使用fork。可能有一种方法可以从fork程序收集精确的数据,但我不知道任何方法。@Mathieurusseau,当然有一些方法可以让父进程从它的子级收集数据。有很多方法。在程序结构中需要最少更改的方法是设置一个共享内存段(在分叉之前)其中存储了子级必须写入的数据结构。其他备选方案包括:让子级将结果写入文件以供父级读取;让他们通过管道将结果发送回父级;让他们将结果发送到消息队列。还有其他不太可能的。感谢clarification,我应该将其添加到我的答案中,还是您想添加您的答案?好的,我设置了一个共享内存,但现在我有两个其他问题:-我不知道何时何地应该分离并删除SM段。-所有的车都有相同的最佳时间(例如:1m45s930ms)
    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.