C 共享内存未同步更新
对于我的项目,我有两项任务 1) Writer:将值写入共享内存中的结构 2) Reader:从结构中读取值 这是编写器代码C 共享内存未同步更新,c,linux,synchronization,ipc,shared-memory,C,Linux,Synchronization,Ipc,Shared Memory,对于我的项目,我有两项任务 1) Writer:将值写入共享内存中的结构 2) Reader:从结构中读取值 这是编写器代码 struct test { volatile int read; volatile int write; }; int main() { // ftok to generate unique key key_t key = ftok("shmfile",65); // shmget returns an identifi
struct test {
volatile int read;
volatile int write;
};
int main()
{
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
struct test *t = (struct test *) shmat(shmid,(void*)0,0);
printf("Going to write into test structure");
t->read = 1;
t->write = 2;
//printf("Data written in memory: %s\n",str);
//detach from shared memory
shmdt((void *)t);
return 0;
}
这是阅读器代码
int main()
{
// ftok to generate unique key
key_t key = ftok("shmfile",65);
// shmget returns an identifier in shmid
int shmid = shmget(key,1024,0666|IPC_CREAT);
// shmat to attach to shared memory
struct test *t = (struct test *) shmat(shmid,(void*)0,0);
printf("Data read from memory: %d:%d\n",t->read,t->write);
//detach from shared memory
shmdt((void *)t);
// destroy the shared memory
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
当我先管理作者,然后管理读者时,一切都很顺利
但是为了调试,我尝试通过lldb同时运行这两个程序。我看到如果writer,writes t->read=1,同时它不会在reader进程中得到更新。若在更改完成后调用shmat,它将反映在reader中
谁能告诉我,如何确保共享内存中的更改同步发生
"It would reflect in reader if it calls shmat after changes are done."
我认为在reader和writer进程中调用shmat的顺序并不重要。唯一需要确保的是,在读卡器进程开始读取之前,有东西被写入共享内存。这可以使用常见的IPC机制实现,如注释部分所述的信号量。我用GDB测试了你的代码。我首先使用gdb执行writer进程,并在't->read=1;'之后暂停writer进程陈述此时,我执行了reader进程,它成功地读取了值1
我还进行了其他一些测试,其中reader进程在writer进程调用shmat之前调用了shmat,并发现了类似的结果
这里我想指出的唯一一点是,只要写入发生在读取之前,调用shmat的顺序就不重要
我在这里添加对您评论的回复,因为它太长了,不适合放在评论部分:
我已经尝试了您建议的步骤,并得到了预期的结果,即读卡器进程中的“t->read”值为1。我使用以下命令编译代码:gcc-g-o writer write.c和gcc-g-o reader read.c。选项-g用于启用调试符号。在此之后,我使用gdb运行writer和reader进程,并在printf语句中添加断点。因此读写器进程都在printf语句处暂停。然后我在writer中执行了't->read=1'。在此之后,我检查了两个进程中的内存转储。两人都在反思1。接下来,我打印了t->read in reader进程的值,它正确地显示了1。这些类型转换的目的是什么?您能详细说明一下吗?哪个演员?都是。您需要一个信号量或互斥来同步读写。。。。其中,一个信号量更适合于确保编写器在同步的基础上先行。感谢您的测试。如果您首先启动生产者,然后转到“t->read=1”;然后启动消费者,一切都会很好。但若你们遵循下面的顺序,事情就不会发生了。1) 同时启动生产商和消费者,直到shmat后打印。2) 然后在生产者3)中执行t->read=1,打印t->read-in-consumer的值。现在我看到consumer中的t->read值仍然为零,顺便说一句,我使用了下面的命令来编译代码cc-pthread-ocons.ccc-pthread-oprod.c