【问题标题】:Shared memory to read an modify arrays共享内存读取修改数组
【发布时间】:2020-02-22 14:57:09
【问题描述】:

我开始学习操作系统的基础知识,我对 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】:

您的程序中缺少进程同步。本质上,您的第二个进程可能会尝试获取此时不存在的共享内存段。由于您正在处理两个可执行文件,因此采购 PID 不是一种选择,因此我们不能使用信号。但是,我们可以让它单独使用共享内存段。

创建一个额外的共享内存段,例如data_ready。您想在两者上都使用 IPC_CREAT,而不是 IPC_EXCL。一旦你的数组被初始化,让你的第一个进程将它设置为一个。因为,我们使用了IPC_CREAT,所以如果进程不存在,任何进程都不会覆盖数据,如果它不存在,第一个进程无论如何都会将它初始化为0。你可以事实上,如果您正在使用它,请在您的第一个流程中删除 IPC_EXCL

让您的第一个进程在初始化数组后将 data_ready 设置为 1,并使用以下命令阻止您的第二个进程 ```while(data_ready==0);````

这是一种相当粗糙的方法。当然,您可以使用线程、信号量、消息队列等做得更好。但是,就目前而言,这应该可以完成工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多