共享内存未同步更新

时间:2019-06-11 02:52:53

标签: 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 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同时运行两者。我看作家是否写t-> read = 1,但同时不会在阅读器进程中进行更新。更改完成后,如果它调用shmat,它将反映在阅读器中。

谁能告诉我,如何确保共享内存中的更改同步发生?

1 个答案:

答案 0 :(得分:0)

   "It would reflect in reader if it calls shmat after changes are done."

我认为在读取器和写入器进程中调用shmat的顺序无关紧要。唯一需要确保的是在读取器进程开始读取之前,已将某些内容写入共享内存。这可以使用注释部分中所述的常用IPC机制(如信号量)来实现。我使用GDB测试了您的代码。我首先使用gdb执行了编写器进程,并在't-> read = 1;'之后暂停了编写器进程。声明。此时,我执行了读取器过程,并成功读取了值1。

我进行了其他一些测试,其中读取器进程在写入器进程之前先调用shmat并发现了相似的结果。

我要在这里指出的唯一一件事是,只要写入发生在读取之前,shmat的调用顺序就无关紧要。

我正在此处添加对您评论的回复,因为它太长了,无法放入评论部分:

我已经尝试了建议的步骤,并获得了预期的结果,即在读取器过程中't-> read'的值为1。我正在使用以下命令来编译我的代码:gcc -g -o writer write。 c和gcc -g -o阅读器read.c。选项-g用于启用调试符号。之后,我使用gdb来运行writer和reader进程,并在printf语句中添加了断点。因此,读取器和写入器过程都在printf语句处暂停。然后我在writer中执行了“ t-> read = 1”。之后,我检查了两个进程中的内存转储。两者都反映了1。接下来,我在读取器进程中打印了t-> read的值,正确显示了1.。