我开始学习操作系统的基础知识,但我在 C 语言和指针方面完全没有经验。我在我的代码中做错了什么,但我不知道如何修复它。我试图填充一个数组,第一个过程初始化数组,第二个过程随机更新值。我的问题是:
- 第一个进程写入共享内存然后退出我希望它在更新后实际读取数组
- 我想我存储数组的方式不对
- 我需要一种方法来告诉每个进程另一个进程何时完成,以保持通信有效,直到第一个进程决定结束为止。以下是我的代码:
第一道工序
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/