【问题标题】:c program loop in fork doesn't stopfork中的c程序循环不会停止
【发布时间】:2021-12-11 07:51:02
【问题描述】:

我正在模拟 F1 训练。我在进程之间使用 fork() 和共享内存。

  1. 我正在为需要运行 5,400,000 的汽车生成一个随机时间。 我 fork() 每辆车。 儿子们必须模拟时代的产生。 父亲负责显示器,他还通过睡眠 (1) 使系统(“清除”)以减慢显示器的速度。

但尽管有 5,400,000 的限制,但程序并没有停止。 节目时长20多分钟不停! 我希望它多次生成显示并停止!

谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>

#define NUMBER_OF_CARS 20
#define MIN 25000 // time generator
#define MAX 40000


int numeroVoiture[NUMBER_OF_CARS] = {44, 77, 11, 33, 3, 4, 5, 18, 14, 31, 16, 55, 10, 22, 7, 99, 9, 47, 6, 63};

typedef struct {

    unsigned int id;

    unsigned int s1;
    unsigned int s2;
    unsigned int s3;

    unsigned int best_S1;
    unsigned int best_S2;
    unsigned int best_S3;


    unsigned int tempsTotal;

    unsigned int best_Circuit;

    unsigned int lap;

    unsigned int compteurStand;

    unsigned int out;
} voiture;

voiture *shared_memory;
voiture copyTableau[NUMBER_OF_CARS];




int faireDesTours(int i);
unsigned int generateNumber(void);
void afficherTableau(void);
int compare (const void * a, const void * b);
void initVoiture(int i);
void sortLap(void);



int main(void)
{
    /***************************************************
    *           Creating shared memory        *
    ****************************************************/
    int segment_id = shmget(IPC_PRIVATE, sizeof(voiture) * NUMBER_OF_CARS, 0666 | IPC_CREAT);
    if (segment_id == -1) {
        perror("shmget() failed !");
        exit(EXIT_FAILURE);
    }

    shared_memory = shmat(segment_id, NULL, 0);
    if (shared_memory == (void *) (-1)) {
        perror("shmat() failed !");
        exit(EXIT_FAILURE);
    }


    /**********************************************************
     *               Creation of child / cars               *
     **********************************************************/
    for (int i = 0; i < NUMBER_OF_CARS; ++i)
    {
        /********  problem fork *********/
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork failed !");
            exit(EXIT_FAILURE);
        }

        /********  child *********/
        if(pid == 0) {
            shared_memory[i].id = numeroVoiture[i]; //each car has a number
            faireDesTours(i); //5400000
        }


        /********  father  *********/
        else {
                wait(NULL);

                system("clear");

                // copy of array
                memcpy( copyTableau, shared_memory, sizeof(copyTableau) );

                //trier Tableau;
                qsort( copyTableau, NUMBER_OF_CARS, sizeof(voiture), compare );
                sortLap();

                afficherTableau();

                sleep(1);
        }

    }


    /********  Detach memory segments  *********/
    shmdt(shared_memory);

    /********  Delete shared memory  *********/
    shmctl(segment_id, IPC_RMID, NULL);


    exit(EXIT_SUCCESS);
}



unsigned int tempsMaxCircuit = 5400000;

int faireDesTours( int i ) {

    initVoiture(i);

    unsigned int tour_complet;

    while (shared_memory[i].tempsTotal <= tempsMaxCircuit) //no exceeded time
    {
        tour_complet = 0;

        srand(time(NULL) + getpid());

        /*   ****       S1     ****     */
        shared_memory[i].s1 = generateNumber();
        if (shared_memory[i].s1 < shared_memory[i].best_S1) {
            shared_memory[i].best_S1 = shared_memory[i].s1;
        }
        shared_memory[i].tempsTotal += shared_memory[i].s1;
        tour_complet += shared_memory[i].s1;
        /* *************************************** */

        if (shared_memory[i].tempsTotal >= tempsMaxCircuit)
        {
            break;
        }
        /*   ****       S2     ****     */
        shared_memory[i].s2 = generateNumber();
        if (shared_memory[i].s2 < shared_memory[i].best_S2) {
            shared_memory[i].best_S2 = shared_memory[i].s2;
        }
        shared_memory[i].tempsTotal += shared_memory[i].s2;
        tour_complet += shared_memory[i].s2;
        /* *************************************** */

        if (shared_memory[i].tempsTotal >= tempsMaxCircuit)
        {
            break;
        }


        /*   ****       S3     ****     */
        shared_memory[i].s3 = generateNumber();
        if (shared_memory[i].s3 < shared_memory[i].best_S3) {
            shared_memory[i].best_S3 = shared_memory[i].s3;
        }
        shared_memory[i].tempsTotal += shared_memory[i].s3;
        tour_complet += shared_memory[i].s3;
        /* *************************************** */


        /*   ****       Best Time Circuit     ****     */
        if (tour_complet < shared_memory[i].best_Circuit) {
            shared_memory[i].best_Circuit = tour_complet;
            shared_memory[i].best_Circuit = tour_complet;
        }
        /* *************************************** */
    }

    return 0;
}



unsigned int generateNumber(void)
{
    return rand()%(MAX-MIN+1)+MIN;
}


void afficherTableau(void) { // Display
    printf("\n\tBest times per complete lap\n");
    printf(" ===================================================================================\n");
    printf(" |     ID   |      s1     |      s2     |      s3     |     Tour     |     LAP     |\n");
    printf(" |==================================================================================\n");
    for (int i = 0; i < NUMBER_OF_CARS; i++){
        printf(" |     %2d   |    %5d    |    %5d    |    %5d    |    %6d    |    %5d    |\n", \
                copyTableau[i].id, \
                copyTableau[i].s1, copyTableau[i].s2, copyTableau[i].s3, \
                copyTableau[i].best_Circuit,\
                copyTableau[i].lap);
    }
    printf(" ===================================================================================\n\n");
}


// function sort
int compare(const void * a, const void * b)
{
    voiture *voitureA = (voiture *)a;
    voiture *voitureB = (voiture *)b;

    return ( voitureA->best_Circuit - voitureB->best_Circuit );
}


// init each structure value of car
void initVoiture(int i) {
    shared_memory[i].s1 = 0;
    shared_memory[i].s2 = 0;
    shared_memory[i].s3 = 0;

    shared_memory[i].best_S1 = MAX;
    shared_memory[i].best_S2 = MAX;
    shared_memory[i].best_S3 = MAX;

    shared_memory[i].best_Circuit = 3 * MAX;
    shared_memory[i].tempsTotal = 0;

    shared_memory[i].lap = 0;
    shared_memory[i].compteurStand = 0;
    shared_memory[i].out = false;
}



void sortLap(void) {

    unsigned int difference;

    for (int i = 1; i < NUMBER_OF_CARS; i++)
    {
        difference = ( copyTableau[i].best_Circuit - copyTableau[i - 1].best_Circuit );

        copyTableau[i].lap = difference;
    }
}

【问题讨论】:

  • 如何简化你的代码,减少调试它的数字?提示,用英文提交,非法语读者更容易理解你的代码

标签: c unix


【解决方案1】:

在核心,你有

    for (int i = 0; i < NUMBER_OF_CARS; ++i)
    {
        /********  problem fork *********/
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork failed !");
            exit(EXIT_FAILURE);
        }

        /********  child *********/
        if(pid == 0) {
                ...
        }


        /********  father  *********/
        else {
                wait(NULL);
                ...
        }
    }

您在孩子中错过了对exit 的呼叫。没有这个,每个孩子都会循环并开始创建自己的孩子。它最终会结束,但不会在无意中创建大量进程之后结束。

顺便说一句,如果父母做的第一件事就是等待孩子结束,那么创建孩子有点奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多