与 fork() 共享内存

shared memory with fork()

我想与fork()一起使用共享内存,但我似乎得不到我想要的结果。

所以我有一个汽车结构数组,我想把它放在共享内存中以便使用fork()。然后我要运行10fork()等所有小朋友都做完了再显示结果! (结果只是他们每辆车的总时间,它是不同的,因为我为每辆车生成一个随机数)。

问题是当我 printf() 我对每个人都有相同的价值,而每个 child 必须不同!因为我只测试了一个循环所以没有共享内存它工作正常但我必须使用共享内存;)。

谁能帮帮我

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

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

typedef struct {
    unsigned int totalTime;
} car;

car *shared_memory;

int drive(int i);
unsigned int generateNumber(void);
void display();

int main(void)
{
    srand( time(NULL) );
    
/***************************************************
*           Creating shared memory        *
****************************************************/
    int segment_id = shmget(IPC_PRIVATE, sizeof(car) * 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              *
     **********************************************************/
    int i;
    pid_t pid = 0;
    for (i = 0; i < NUMBER_OF_CARS; i++) {
        pid = fork();
        if (pid == 0)
            break;
    }

    switch (pid) {
        case -1:
            perror("fork failed !");
            exit(EXIT_FAILURE);

        case 0:
            drive(i); //540000
            exit(EXIT_SUCCESS);

        default:
            display();
            /********  wait for children to finish  *********/
            for (int j = 0; j < NUMBER_OF_CARS; j++) {
                wait(NULL);
            }
    }

    /********  Detach memory segments  *********/
    shmdt(shared_memory);
    /********  Delete shared memory  *********/
    shmctl(segment_id, IPC_RMID, NULL);

    exit(EXIT_SUCCESS);
}

unsigned int timeMaxi = 540000;

int drive( int i ) {
    unsigned int number;
    while ( shared_memory[i].totalTime <= timeMaxi ) //time pas dépassée
    {
        number = generateNumber();
        shared_memory[i].totalTime += number;
    }
    return 0;
}

void display(void) {
    for (int i = 0; i < NUMBER_OF_CARS; i++){
            printf("Total %d : %d\n", i, shared_memory[i].totalTime);
    }
}

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


结果:

./prog
Total 0 : 564634
Total 1 : 564634
Total 2 : 564634
Total 3 : 564634
Total 4 : 564634
Total 5 : 564634
Total 6 : 564634
Total 7 : 564634
Total 8 : 564634
Total 9 : 564634

你的共享内存没有问题。问题是所有 children 都以 generateNumber() 中相同的随机数序列结束。您只调用 srand() 一次,在所有分叉之前,所以每个 child 都会生成完全相同的随机数。

只需在每个 child 中调用 srand(),然后再调用 drive()srand(time(NULL)) 是不够的,因为它们可能会在同一秒内全部 运行,但您可以使用 getpid() 或其他一些适当的方法作为 srand() 的参数在每个 child 中以不同的方式播种随机数生成器。