Shared mutex in C error in Init

569 views Asked by At

I am trying to make a program with shared memory and execute more than 1 time the same program to increase a value, all this using one shared mutex.

The problem is that in my second execution, the funcion mutex_init fail.

any ideas?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <mqueue.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>

#define SM_SIZE sizeof (struct shared)
#define min 4
#define max 10

struct shared
{
    pthread_mutex_t mutex;
    int i;

};

char *shared1_name="asdf";


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

int id_sharedMem1;
int i,j,loops;
struct shared *memoriaC;

loops = atoi(argv[1]);

id_sharedMem1 = shm_open ( shared1_name , O_RDWR, 644 );    

if(id_sharedMem1==-1)
    {    
    id_sharedMem1 = shm_open ( shared1_name , O_CREAT|O_RDWR, 644 );
    if ( id_sharedMem1 == -1 || ftruncate ( id_sharedMem1, SM_SIZE ) == -1) 
        {
        printf("open %s\n",strerror(errno));
        exit(1);
        }

    memoriaC = mmap ( NULL, SM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, id_sharedMem1, 0 );
    if ( memoriaC == (void *) -1)
        {
        perror ( "mmap" );
        exit(1);
        }
    memoriaC->i=0;
    if (pthread_mutex_init(&(memoriaC->mutex), NULL)!=0)
            printf("mutex init 1 %s\n",strerror(errno));

    }else
        {

        if (pthread_mutex_init(&(memoriaC->mutex), NULL)!=0)
                printf("mutex init 2 %s\n",strerror(errno));

        }

    if(pthread_mutex_lock ( &(memoriaC->mutex))!=0)
            printf("mutex lock %s\n",strerror(errno));

    i = memoriaC->i + 1;
    memoriaC->i = i+loops;
    close ( id_sharedMem1 );
    for(j=0;j<loops;j++)
        i++;

    printf("i= %d\n",i);

    if(pthread_mutex_unlock ( &(memoriaC->mutex))!=0)
        printf("mutex unlock %s\n",strerror(errno));


//shm_unlink ( shared1_name );                      
}
1

There are 1 answers

2
Brian McFarland On

There a couple "tricks" required to get shared-memory mutexes right:

1) You must guarantee only one process / thread creates / initializes the mutex. You can improve chances of getting this right if you use O_EXCL when creating the shared memory, then make the process that succeeds in creating the shared memory responsible for initializing the mutex. This may or may not be a sufficient strategy in itself.

2) You must enable sharing the mutex using pthread_mutexattr_setpshared` and related functions. It is not sufficient to place the mutex in shared memory.

3) You should also understand pthread_mutexattr_settype and know when and why to use the different types.

4) You should use pthread_mutexattr_setrobust appropriately, provided your OS supports it. Otherwise you get a deadlock if a process exits while holding the lock.