Reputation: 6008
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
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