共享内存以读取修改数组

问题描述 投票:0回答:1

我开始学习OS的基础知识,我对C和指针一无所知。我在代码中做错了什么,但我不知道如何解决它。我试图填充一个数组,第一个过程初始化数组,第二个过程随机更新值。我的问题是:

  1. 第一个进程写入共享内存,然后退出,我希望它在更新后实际读取数组]
  2. 我认为我以错误的方式存储数组
  3. 我需要一种方法来告诉每个进程何时完成另一个进程,以保持通信畅通,直到第一个进程确定结束为止。以下是我的代码:

第一步


int main()

{
    key_t key; 
    int shm_id;
    int *shm_ptr;

    if ((key = ftok("/tmp", 'y')) == -1)  
    {   
        perror("ftok() failed");   
        exit(EXIT_FAILURE);
    }

    shm_id = shmget(key, SIZE*sizeof(int), IPC_CREAT | IPC_EXCL | 0600 );
    if (shm_id == -1)  
    {           
        perror("Failed to get memory");   
        exit(EXIT_FAILURE);
    }

    shm_ptr = (int *) shmat ( shm_id, NULL, 0);
    if (shm_ptr == (int *) -1)
    {
        perror( "shmat failed" ) ;
        exit( EXIT_FAILURE ) ;
    }

    printf("Array Initialized as : \n");

    for(int i=0; i<SIZE-1; i++)
    {
        shm_ptr[i]=-1;
    }
    // for(int i = 0; i< 30; i++)
    // {
    //  printf(" %d", shm_ptr[i]);
    // }

    shmdt(shm_ptr);

    // shmctl(shm_id,IPC_RMID, NULL);

    return 0;
}

第二过程

int main()

{
    key_t key;
    int sum = 0;
    int shm_id;
    int *shm_ptr;

    key = ftok("/tmp", 'y');

    shm_id = shmget( key, 0 , 0600 );
    if (shm_id == -1)  
    {
        perror("Failed to get memory");   
        exit(EXIT_FAILURE);
    }
    shm_ptr = (int*) shmat(shm_id,NULL,0);

    printf("Client array \n");
    srand(time(NULL));
    for(int i = 0; i< 30; i++)
    {
        shm_ptr[i] = rand() % 20 + 1;
    }
    for(int i = 0; i< 30; i++)
    {
        printf(" %d", shm_ptr[i]);  
    }
    shmdt(shm_ptr);

    shmctl(shm_id,IPC_RMID, NULL);

    return 0;

}
c linux process ipc shared-memory
1个回答
0
投票

程序中缺少进程同步。从本质上讲,您的第二个过程可能会尝试获取当前不存在的共享内存段。由于您要处理两个可执行文件,因此不能选择获得PID,因此,我们不能使用信号。但是,我们可以使其仅与共享内存段一起使用。

创建一个额外的共享内存段,例如data_ready。您想在两者上都使用IPC_CREAT,但不要同时使用IPC_EXCL。数组初始化后,将您的第一个过程设置为一个。由于我们使用了[[IPC_CREAT,因此如果该进程不存在,并且该进程不存在,则任何一个进程都不会覆盖数据。无论如何,第一个进程将其初始化为0。如果要使用,请在第一个过程中<> IPC_EXCL。 一旦您的第一个进程将数组初始化后,将data_ready设置为1,并使用诸如```while(data_ready == 0);````

这是执行此操作的粗略方法。当然,您可以使用线程,信号量,消息队列等来做得更好。但是,就目前而言,这应该可以完成工作。
© www.soinside.com 2019 - 2024. All rights reserved.