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 );                      
}
				
                        
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_EXCLwhen 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_settypeand know when and why to use the different types.4) You should use
pthread_mutexattr_setrobustappropriately, provided your OS supports it. Otherwise you get a deadlock if a process exits while holding the lock.