Currently I'm porting a software from Windows to Mac OS X in C++.
In Windows, there's an abandoned state in global named mutex which means that current owner process of the mutex is gone without releasing the mutex. (It will likely be caused by application crash)
Because of abandoned state exists, trying to lock for abandoned mutex will not cause deadlock.
If there's no abandoned state, it will wait forever for a mutex which is not owned by anyone.
There's another approach by using timeout to assume the mutex is abandoned if unable to obtain the mutex for certain time, but it is not a perfect solution compared against abandoned mutex way. In the worst case, accidentally two processes can access to the object locked by the mutex.
Is there any mutex support abandoned state in Mac OS X/Linux?
I researched for the boost library, the boost library has a named mutex, but that one is based on a shared file so it does not have abandoned state.
Please give me some advise.
Well maybe a little late but you can use the pthread_mutexattr_t
to set your mutex attribute to be shared between pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
API. This mutex value needs to be shared between processes by storing it into a named shared memory.
Here is a code snippet:
int key = ftok(NAMED_MEMORY, ID_TAG);
if (-1 == key)
{
printf("Unable to name shared memory\n");
exit(1);
}
// Create the segment exclusively (if the segment already exists then a combination of IPC_CREAT | IPC_EXCL returns an error EEXIST)
int m_iShmid = shmget(key, TOTAL_SIZE, READ_WRITE_PERMISSIONS | IPC_CREAT | IPC_EXCL);
if (m_iShmid < 0)
{
if (EEXIST == errno)
{
// if the shared memory already exists we only fetch the id to that memory
m_iShmid = shmget(key, TOTAL_SIZE, READ_WRITE_PERMISSIONS);
}
if (m_iShmid < 0)
{
printf("Unable to create shared memory - %s\n",strerror(errno));
exit(1);
}
else
printf("Attached to the existing shared memory\n");
}
else
printf("Created new shared memory\n");
// Now we attach the segment to our data space.
mutex = reinterpret_cast<pthread_mutex_t*>(shmat(m_iShmid, NULL, 0));
if (reinterpret_cast<pthread_mutex_t*>(-1) == mutex)
{
printf("Unable to attach shared memory to the process - %s\n",strerror(errno));
exit(1);
}
// Now we can set this mutex to be shared between processes
pthread_mutex_t* mutex;
pthread_mutexattr_t mutexAttr;
ret = pthread_mutexattr_init(&mutexAttr);
if(ret != 0)
{
printf("pthread_mutexattr_init failed - err=%d\n",ret);
exit(1);
}
ret = pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
if(ret != 0)
{
printf("pthread_mutexattr_setpshared failed - err=%d\n",ret);
exit(1);
}
ret = pthread_mutexattr_setrobust_np(&mutexAttr, PTHREAD_MUTEX_ROBUST_NP);
if(ret != 0)
{
printf("pthread_mutexattr_setrobust_np failed - err=%d\n",ret);
exit(1);
}
ret = pthread_mutex_init(mutex, &mutexAttr);
if(ret != 0)
{
printf("pthread_mutex_init failed - err=%d\n",ret);
exit(1);
}
// ------ Use the mutex from here on between processes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With