【问题标题】:shared memory with fork()与 fork() 共享内存
【发布时间】:2021-12-04 13:36:19
【问题描述】:

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

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

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

谁能帮帮我

#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

【问题讨论】:

  • 在所有孩子都完成之前,您不应致电display()。在他们写入共享内存之前,您正在打印。
  • 还是同样的问题,我在条件之外调用了函数但没有任何变化。

标签: c unix


【解决方案1】:

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

在调用drive() 之前,只需在每个孩子中调用srand()srand(time(NULL)) 还不够,因为它们可能都在同一秒内运行,但您可以使用 getpid() 或其他适当的方法作为 srand() 的参数,以不同的方式在每个孩子中播种随机数生成器.

【讨论】:

    猜你喜欢
    • 2010-12-30
    • 2013-03-06
    • 2011-02-10
    • 2011-07-31
    • 2012-04-26
    • 2021-01-19
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    相关资源
    最近更新 更多