2

In process-1 I am trying to write the data into shared memory. At the same time in process-2 I am reading the data from the same shared memory. in this case I need to provide synchronization between these two processes. if I will go through unnamed semaphores (using shm_init(),mmap()),will it work or not?

I have written code like this will it work or not?

fd = shm_open("shm_name", O_CREAT| O_RDWR, S_IRUSR | S_IWUSR);

sema = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE,MAP_SHARED , fd, 0);

sem_init(sema, 1, 1);
sstn
  • 3,050
  • 19
  • 32

1 Answers1

6

The general approach will work. Note the following however:

  • The name argument to shm_open(3) should start with a slash. Pass "/shm_name" instead. (On Linux with glibc, it happens to work without the slash, IIRC.)
  • You need to resize fd with an ftruncate(2), or you'll get a SIGBUS when you try to access the shared memory. Whenever you mmap(2) a file, any memory you access in the mapping must actually exist in the file, and POSIX shared memory objects work the same way. (On Linux, they're implemented as files under /dev/shm, which uses an in-memory tmpfs.)
  • If you plan to use the semaphore to synchronize operations on a shared memory mapping, then it's redundant to create a separate shared memory mapping just for the semaphore. Make it a part of the mapping you're synchronizing operations on instead.

For the latter, you could do e.g. the following:

typedef struct Shared_mem {
    sem_t sem;
    int shared_data[100];
} Shared_mem;

...

shared_mem = mmap(NULL, sizeof(Shared_mem), PROT_READ | PROT_WRITE,
                  MAP_SHARED, fd, 0);

...

sem_init(&shared_mem->sem, 1, 1);
Ulfalizer
  • 4,664
  • 1
  • 21
  • 30
  • A big +1 to this response. I got involved with a piece of code that did the same thing: use mmap for interprocess sharing, but use a bucketload of shm_* calls to create the named semaphores, which required all kinds of reverse-engineering, filename building (/dev/shm/sem.*) for multiple files (yes, semaphores plural), string munging, etc. I had the same idea and "moved" the named semaphores as unnamed semphores into the file that was already being shared, and all that ugliness went away! – Brian Carcich Apr 17 '23 at 21:59
  • The only hiccup I had was that the original code would call sem_init on the named semaphores, which is not necessary, whether it was the process creating a new semaphore or opening an existing semaphore. Apparently that did not matter for named semaphores, because the ugly code worked. However, when I converted it to unnamed semaphores in mmap'ed file memory, it mattered big time. My point is that when the man page for sem_init says "Initializing a semaphore that has already been initialized results in undefined behavior," pay attention! – Brian Carcich Apr 17 '23 at 22:05