Home > database >  shared memory with fork()
shared memory with fork()

Time:10-18

I would like to use shared memory with fork() but I can't seem to get the result I want.

So I have a car Structure array and I would like to put it in shared memory in order to use fork(). Then I want to run 10 fork() and wait until all the kids are done to display the results! (the result is just their total time of each car, it is different because I am generating a random number for each car).

The problem is when I printf() I have the same value for everyone, whereas it must be different for each child! because i tested with just a loop so without shared memory it works fine but i have to use shared memory;).

Could anyone help me please

#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;
}


The result :

./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

CodePudding user response:

There's nothing wrong with your shared memory. The problem is that all of the children are ending up with the same random number sequence in generateNumber(). You're only calling srand() once, before all the forks, so every child is going to generate the exact same random number.

Just call srand() in each child before calling drive(). srand(time(NULL)) won't be enough, because they'll likely all run within the same second, but you could use getpid() or some other appropriate method as an argument to srand() to seed the random number generator in each child differently.

  • Related