c - 共享内存读取修改数组

标签 c linux process ipc shared-memory

我开始学习操作系统的基础知识,但我在 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;

}

最佳答案

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

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

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

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

关于c - 共享内存读取修改数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572357/

相关文章:

linux - Windows 和 Linux IPC 的信号

python - 在 Linux 上使用 Python 中受密码保护的 Excel 工作表

c - 这个代码段告诉我什么?

javascript - 如何判断子 Node.js 进程是否来自 fork()?

macos - Hadoop2.7.3 : Cannot see DataNode/ResourceManager process after starting hdfs and yarn

c - 在 C 中使用 argp 解析单个选项的多个值

c - 在 C 中使用带位运算符的小整数

C strtok,回车输入

c - Unix 中的 Strace 命令

linux - 如何grep特定列中值小于0.2的行?