Kam
Kam

Reputation: 6008

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?

Upvotes: 3

Views: 10884

Answers (1)

pilcrow
pilcrow

Reputation: 58524

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.).

Upvotes: 4

Related Questions