等同于 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 的命名互斥锁? [复制]的主要内容,如果未能解决你的问题,请参考以下文章