在Mac OS X中相当于Windows的名为mutex?

时间:2014-05-28 19:58:46

标签: c++ linux macos mutex interprocess

目前我正在使用C ++将软件从Windows移植到Mac OS X.

在Windows中,全局命名互斥锁中存在一个被放弃的状态,这意味着互斥锁的当前所有者进程在不释放互斥锁的情况下消失了。 (这可能是由应用程序崩溃引起的)

由于存在废弃状态,尝试锁定已弃用的互斥锁不会导致死锁 如果没有废弃的状态,它将永远等待一个不属于任何人的互斥锁。

还有另一种方法是使用超时来假设如果在一定时间内无法获得互斥锁,则互斥量被放弃,但与废弃的互斥方式相比,它不是一个完美的解决方案。在最坏的情况下,意外地两个进程可以访问由互斥锁锁定的对象。

在Mac OS X / Linux中是否有任何互斥锁支持被放弃状态?

我研究过boost库,boost库有一个名为mutex,但是那个基于共享文件,所以它没有放弃状态。

请给我一些建议。

2 个答案:

答案 0 :(得分:2)

好吧可能有点晚了但您可以使用pthread_mutexattr_t设置您的互斥锁属性在pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); API之间共享。需要通过将进程存储到命名的共享内存中来共享此互斥锁值。

以下是代码段:

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

答案 1 :(得分:0)

鉴于此处唯一的答案是使用古老的ftok()/ shmget()方法来获取共享内存,我将指向您开发和维护的库:

https://github.com/cubiclesoft/cross-platform-cpp

具体来说,您需要&#39; sync / sync_mutex。*&#39;和&#39; sync / sync_util。*&#39;文件。你可以使用现代POSIX pthreads和POSIX共享内存为* NIX风格的操作系统上的命名对象获得Windows,Mac,Linux,以及一些具有单个Sync :: Mutex类的变体。该代码还处理一些场景,例如只允许一个线程创建并初始化一个对象,其他线程等到对象完全初始化后再继续。

用于使用POSIX信号量的库的Sync部分,但我发现在某些操作系统上这些操作非常破碎,而共享内存和pthread在这些操作系统上共享更广泛的支持。

就被放弃的状态而言,操作系统本身必须拥有同步对象以处理该特定方案。也就是说,进程退出并且所有获取的同步对象都被标记为已放弃。当进程退出时,Windows内核通常会处理同步对象的清理。其他操作系统内核不会/不能做到这一点。一种可能的选择是为其他操作系统编写系统服务或驱动程序,其唯一目的是处理废弃状态并清理和重新初始化对象。当然,如果你想出一个从应用程序本身处理废弃对象的好方法,请告诉我/提交补丁/等。