等同于 Mac OS X 中 Windows 的命名互斥锁? [复制]

Posted

技术标签:

【中文标题】等同于 Mac OS X 中 Windows 的命名互斥锁? [复制]【英文标题】:Equivalent of Windows's named mutex in Mac OS X? [duplicate] 【发布时间】:2014-05-28 19:58:45 【问题描述】:

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

在 Windows 中,全局命名互斥体中存在废弃状态,这意味着互斥体的当前所有者进程已消失,而未释放互斥体。 (很可能是应用崩溃造成的)

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

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

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

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

请给我一些建议。

【问题讨论】:

只是发布链接不是明确的答案 - 但您可能会研究 pthread 静音,包括强大的互斥锁。请参阅本主题中的 cmets:***.com/questions/4424193/… 嗨orpheist!感谢您的回答!我看了一下健壮的 pthread,但它看起来不支持进程间锁定......我开始觉得解决方案可能是信号量(我找不到它是否像健壮的 pthread 一样健壮),或者使用文件锁定(将被释放在进程崩溃时)。我需要更多的研究......无论如何,非常感谢! 【参考方案1】:

可能有点晚了,但您可以使用pthread_mutexattr_t 将您的互斥属性设置为在pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); API 之间共享。这个互斥量值需要在进程之间共享,方法是将其存储到一个命名的共享内存中。

这是一个代码sn-p:

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

【讨论】:

【参考方案2】:

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

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

具体来说,您需要 'sync/sync_mutex.*' 和 'sync/sync_util.*' 文件。您可以获得 Windows、Mac、Linux 以及可能具有单个 Sync::Mutex 类的一些变体,这些变体使用现代 POSIX pthreads 和 POSIX 共享内存用于 *NIX 样式操作系统上的命名对象。该代码还处理一些场景,例如只让一个线程创建和初始化一个对象,而其他线程等到对象完全初始化后再继续。

该库的 Sync 部分曾经使用 POSIX 信号量,但我发现这些信号量在某些操作系统上非常不完善,而共享内存和 pthread 在这些相同的操作系统上共享更广泛的支持。

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

【讨论】:

以上是关于等同于 Mac OS X 中 Windows 的命名互斥锁? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何配置Mac OS X 与 Windows之间共享网络

Windows下虚拟机安装Mac OS X ----- VM12安装Mac OS X 10.11

VMWare安装苹果Mac OS X

Windows下怎么制作Mac OS X启动U盘

Mac OS X怎样访问Windows/Linux共享

Mac Os X 中类似 Windows 的 Qt4 菜单栏