Shared Memory Between C Programs

I'm involved in a project with multiple teams which are developing C code for a Linux machine and we would like to have our program pass data to one of the other group's programs. The immediate idea is to have shared memory between the programs which would simply consist of variables whose size and offset from the beginning of the file are specified and have one program read from it while the other writes to it.

Will we run into any problems if we simply treat this file like any other file in our respective programs (i.e. fd = open(....) and just write to/read from fd at our leisure) or are there special steps that need to be taken in order to avoid simultaneously accessing the same data or something of that nature?

I don't see the point of using read()/write() if you're also mapping in shared memory. It still ought to work, I think, but it really defeats the point.

You don't need to hardcode offsets, either, you can use C's own complex data structures inside shared memory:

typedef struct mytype
{
      int type;
      char buf[512];
      float whatever;
} mytype;

...

mytype *mem=mmap(...);
mem[0].type=1;
strcpy(mem[0].buf, "this is a string");
mem[0].whatever=3.14159f;
mem[1].type=2;
strcpy(mem[1].buf, "this is another string");
mem[1].whatever=1.23456f;

The only caveat is that the structure can't hold pointers. Pointers from one process won't make sense in another. Even pointers to inside the shared area might not work since the shared area might not always end up in the same address in every process. If you need something like pointers, use long integers that mean the index of an array inside the shared memory (or just an offset from the beginning of shared memory).

yes, always, even if you were just read/writing the files all the time instead of mapping them.

Since you have the file open anyway, you can use POSIX advisory locking to control who gets to access the memory when. These functions will block when the section you ask for is busy with something else.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

// More than one thing can read simultaneously.
int readlock(int fd, int pos, int len)
{
        struct flock l;

        memset(&l, 0, sizeof(l));
        l.l_type=F_RDLCK;
        l.l_whence=SEEK_SET;
        l.l_start=pos;
        l.l_len=len;

        if(fcntl(fd, F_SETLKW, &l) != 0)
        {
                perror("Couldn't set rdlock");
                return(-1);
        }

        return(0);
}

// ...but everything has to wait while something's writing.
int wrlock(int fd, int pos, int len)
{
        struct flock l;

        memset(&l, 0, sizeof(l));
        l.l_type=F_WRLCK;
        l.l_whence=SEEK_SET;
        l.l_start=pos;
        l.l_len=len;

        if(fcntl(locked, F_SETLKW, &l) != 0)
        {
                perror("Couldn't set wrlock");
                return(-1);
        }

        return(0);
}

int unlock(int fd, int pos, int len)
{
        struct flock l;
        memset(&l, 0, sizeof(l));
        l.l_type=F_UNLCK;
        l.l_whence=SEEK_SET;
        l.l_start=pos;
        l.l_len=len;

        if(fcntl(locked, F_SETLK, &l) != 0)
        {
                perror("Couldn't unlock");
                return(-1);
        }

        return(0);
}

Dude, Corona, your posts are always awesome!

Thanks :slight_smile: