Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InterProcess communication -- Locking Mutex in shared memory

I have 2 processes that will execute the same code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <pthread.h>


#ifndef _POSIX_THREAD_PROCESS_SHARED
#error This system does not support process shared mutex
#endif

struct shm_content
{
      pthread_mutex_t   mutex;
};

pthread_mutex_t    *mptr; //Mutex Pointer
pthread_mutexattr_t matr; //Mutex Attribute

int   shared_mem_id;      //shared memory Id
int   *mp_shared_mem_ptr; //shared memory ptr -- pointing to mutex

int main (void)
{
    int  rtn;
    size_t shm_size;

    /* initialize shared memory segment */
    shm_size = 1*sizeof(pthread_mutex_t);

    if ((shared_mem_id = shmget(IPC_PRIVATE, shm_size, 0660)) < 0)
    {
        perror("shmget"), exit(1) ;
    }
    if ((mp_shared_mem_ptr = (int *)shmat(shared_mem_id, (void *)0, 0)) == NULL)
    {
        perror("shmat"), exit(1);
    }

    //Offset to find the location of the mutex variable in the shared memory
    shm_content* pcontent = reinterpret_cast<shm_content*>(mp_shared_mem_ptr);

    mptr = &(pcontent->mutex);

    // Setup Mutex
    if (rtn = pthread_mutexattr_init(&matr))
    {
        fprintf(stderr,"pthreas_mutexattr_init: %s",strerror(rtn)),exit(1);
    }
    if (rtn = pthread_mutexattr_setpshared(&matr,PTHREAD_PROCESS_SHARED))
    {
        fprintf(stderr,"pthread_mutexattr_setpshared %s",strerror(rtn)),exit(1);
    }
    if (rtn = pthread_mutex_init(mptr, &matr))
    {
        fprintf(stderr,"pthread_mutex_init %s",strerror(rtn)), exit(1);
    }

        // Lock mutex and then wait for signal to relase mutex
    printf("child mutex lock \n");
    pthread_mutex_lock( mptr );
    printf("child mutex locked\n");

    int i = 0; // :)

    //busy wait
    while (i<10)
    {
        printf("Busy Wait!!! I AM PROCESS 1\n");
        //in the second process will change this line to :
        //printf("Busy Wait!!! I AM PROCESS 2\n");
        sleep(2);
    }

    printf("child mutex unlock\n");
    pthread_mutex_unlock( mptr );
    printf("child mutex unlocked\n");

}

I am expecting that the second process will only be able to acquire the mutex once the first process releases it, but now it seams that there's 2 copies of the mutex and each process can lock its own.

Any ideas?

like image 390
Kam Avatar asked Jun 27 '26 02:06

Kam


1 Answers

if ((shared_mem_id = shmget(IPC_PRIVATE, shm_size, 0660)) < 0)
                            ^^^^^^^^^^^

Your shared memory is private to each process, and thus the mutex therein is private to each process.

The memory and mutex would be inherited across forks, but that's not relevant to your current design.

You need non-private shared memory. This would be a good time to drop the SysV-style shared memory interface (shmget(), etc.) and adopt the simpler POSIX interface (shm_open(), etc.).

like image 135
pilcrow Avatar answered Jun 28 '26 14:06

pilcrow



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!