Shared memory not getting updated synchronously

Viewed 1502

For my project I have two tasks 1)Writer : Write value into a structure in shared memory 2)Reader: Read value from the structure

Here is the writer code

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; 
} 

Here is the reader Code

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; 
} 

When I first run the writer and then the reader , things work fine.

But for debugging, I tried to run both at the same time via lldb. I see if writer, writes t->read = 1 , at the same time it would not get updated in the reader process. It would reflect in reader if it calls shmat after changes are done.

Could anyone please tell me , how to make sure changes in shared memory happens synchronously ?

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

I think the sequence in which shmat gets called in the reader and writer processes does not matter. The only thing that needs to be ensured is that something gets written to the shared memory before the reader process starts reading. This can be achieved using the usual IPC mechanisms such as semaphores as stated in the comments section. I tested your code using GDB. I executed the writer process first using gdb and paused the writer process after the 't->read = 1;' statement. At this point i executed the reader process and it successfully read the value 1.

I carried out few other tests where the reader process calls shmat before the writer process does and found similar results.

The only thing i want to point out here is that the order in which shmat gets called should not matter as long as write happens before read.

I am adding the response to your comments here as it is a bit too long to fit in the comments section:

I have tried out the steps you suggested and got the expected result i.e. value of 't->read' in reader process is 1. I am using the following commands to compile my code: gcc -g -o writer write.c and gcc -g -o reader read.c . The option -g is for enabling debug symbols. After this i used gdb to run both the writer and reader processes and added breakpoints at the printf statements. So both the reader and writer processes were paused at the printf statement. Then i executed 't->read = 1' in writer. After this i checked the memory dump in both the processes. Both were reflecting 1. Next i printed value of t->read in reader process which rightly displayed 1.

Related