相当于 Mac OS X 中 Windows 命名的互斥锁?

Equivalent of Windows's named mutex in Mac OS X?

本文关键字:OS Mac Windows 相当于      更新时间:2023-10-16

目前我正在用c++将一个软件从Windows移植到Mac OS X。

在Windows中,在全局命名互斥中有一个废弃状态,这意味着互斥的当前所有者进程在不释放互斥的情况下已经消失。(很可能是应用程序崩溃造成的)

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

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

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

我研究了boost库,boost库有一个命名互斥锁,但这个互斥锁是基于共享文件的,所以它没有放弃状态。

请给我一些建议

也许有点晚了,但是你可以使用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 memoryn");
    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 - %sn",strerror(errno));
        exit(1);
    }
    else
        printf("Attached to the existing shared memoryn");
}
else
    printf("Created new shared memoryn");
// 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 - %sn",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=%dn",ret);
    exit(1);
}
ret = pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
if(ret != 0)
{
    printf("pthread_mutexattr_setpshared failed - err=%dn",ret);
    exit(1);
}
ret = pthread_mutexattr_setrobust_np(&mutexAttr, PTHREAD_MUTEX_ROBUST_NP);
if(ret != 0)
{
    printf("pthread_mutexattr_setrobust_np failed - err=%dn",ret);
    exit(1);
}
ret = pthread_mutex_init(mutex, &mutexAttr);
if(ret != 0)
{
    printf("pthread_mutex_init failed - err=%dn",ret);
    exit(1);
}
// ------ Use the mutex from here on between processes

考虑到这里唯一的答案是使用古老的ftok()/shmget()方法来获取共享内存,我将指向我开发和维护的一个库:

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

具体来说,你需要的是'sync/sync_mutex '。*和sync/sync_util。*’文件。在Windows、Mac、Linux以及其他一些类型的操作系统中,使用现代POSIX pthread和POSIX共享内存,在* nix风格的操作系统上使用单个Sync::Mutex类。这段代码还处理了一些场景,比如只让一个线程创建和初始化对象,而其他线程要等到对象完全初始化后才能继续。

库的Sync部分过去使用POSIX信号量,但我发现在某些操作系统上,当共享内存和pthread在相同的操作系统上共享更广泛的支持时,这些信号量是相当坏的。

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