Search code examples
cmmap

shared memory/mmap


I'm very new to C and Unix, so this might be a silly problem. Yesterday I've been trying to make 2 programs that communicate with each other via shared memory. One is the receiver, the other is the sender.

The receiver below sets up the shared memory and also 2 semaphores (one for reading the other for writing) and waits for something to receive in a loop, said loop is terminated if the received string is empty. Both programs use 3 flags: -m (shared_memory_name) -w (writing_semaphore_name) -r (reading_semaphore_name)

int main(int argc, char** argv)
{

 //sem_in,sem_out,shared_mem_fd,getopt stuff

 //getopt()...

while(1)
{   
    //waiting for sender to change the sem

    if(sem_wait(sem_out)==-1){ //waits for the sender to change the semaphore
            //error
    }
    char* data =  mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);

    if(data == MAP_FAILED){
        //error
    }

    if(strlen(data) == 0){
        //terminate program
    }       


    if(sem_post(sem_in)==-1){
        //error
    }

}

//close sems and shared memory

return 0
}

The sender below is suppose to open the shared memory FD and put in something, that something is the additional argument I get from argv[optind], usually a string.

int main(int argc, char** argv){

//sems,getopt variables,filedescriptor

char* data;

//getopt()

data = argv[optind];

if(sem_in == SEM_FAILED || sem_out == SEM_FAILED || SHM_FD == -1){
        //error
}

//printf("waiting\n");

if(sem_wait(sem_in)==-1){
        //error
}

data = mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);    

if(data==MAP_FAILED){
    //error
}

if(sem_post(sem_out)==-1){
        //error
}

close(shared memory);

return 0;
}

This is how i used the program:

./receiver -m /mem1 -w /s1 -r /s2 (creates the memory and sems and waits)
waiting

./sender -m /mem1 -w /s1 -r /s2 hello (send a string)

./receiver -m /mem1 -w /s1 -r /s2
waiting
empty

Despite me sending something, the receiver says the string is empty. The semaphores were changed, so theres that.

Like I said, I'm pretty much a rookie when it comes to this so I easily make stupid mistakes, I hope I explained my issue well enough, any help would be appreciated.

P.S. Variable names were in my language so forgive me if I forgot to translate some, also I was experimenting a lot so some includes from previous versions are still there...


Solution

  • The problem is that you're not storing anything in the shared memory. You've got the following two lines in the code...

    data = argv[optind];
    
    data = (char*)mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
    

    The second one overwrites the contents of data and then you don't copy anything into the memory it points at.

    Since it doesn't really do anything useful, you should remove the first line. To populate the shared memory add this line after you open it.

    memcpy(data,argv[optind],strlen(argv[optind])+1);
    

    And since you're no longer pointing data at the argument you'll need to change the opening of the shared memory too.

    data = (char*)mmap(NULL,strlen(argv[optind])+1,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
    

    You'll note I've added 1 to the length of the string - that's to ensure there is enough space to include the NUL terminating character as well.