【问题标题】:How do you find out if a mutex object already exists in Linux?如何确定 Linux 中是否已经存在互斥对象?
【发布时间】:2012-11-24 01:11:52
【问题描述】:

我目前正在尝试将针对 WIN32 编写的多线程库移植到 Android/Linux,但在尝试映射 WIN32 互斥锁具有的特定功能时似乎遇到了一些问题。

来自 Windows 互斥对象的文档:

其他进程中的线程可以打开现有互斥锁的句柄 通过在对 CreateMutex 的调用中指定对象名称来创建对象。如果一个 同名互斥对象已经存在,GetLastError 返回 ERROR_ALREADY_EXISTS。

我无法在 Linux 手册页中找到与 Windows API 提供的内容类似的任何信息。

我问这个问题的主要原因是我要移植的互斥体创建代码包含:

isCreator = !(::GetLastError() == ERROR_ALREADY_EXISTS);

其中isCreator 是布尔数据类型。 (不确定它的用途,但我认为它很重要)。

编辑:

mutex = PTHREAD_MUTEX_INITIALIZER;
// attributes??

if (pthread_mutex_init(&mutex, NULL) != 0) {
 throw Nv_EXCEPTION(XCPT_ResourceAllocationFailure, GetLastError());
}

【问题讨论】:

  • 你在 Linux 上使用什么互斥锁?
  • ERROR_ALREADY_EXISTS 在很多情况下确实不是“错误”;如果它只是意味着之前的线程已经创建了它。当您实际上第一次创建互斥锁时,查看 sn -p isCreator 设置。
  • @seand:最大的问题是 Windows 互斥锁似乎是系统范围的,而 pthread 互斥锁是每个进程的。
  • 那么如果某个特定线程/进程已经创建了一个互斥锁,那么在 Linux 上没有办法查明吗?是因为 Linux 上的互斥锁没有命名吗?
  • 这完全取决于您如何实现互斥锁。

标签: android linux windows multithreading porting


【解决方案1】:

命名的进程间互斥锁的最简单模拟可能是 named realtime semaphore 初始化为值一 (1)。尝试sem_open("/the_sem", O_CREAT|O_EXCL, mode, 1)。如果您不是第一个,O_EXCL 将失败并显示 EEXIST,如果您不是第一个,后续的没有标志的 sem_open 应该会成功:

sem_t *sem;
int isCreator = 0;

if ((sem = sem_open("/the_sem", O_CREAT|O_EXCL, mode, 1)) != SEM_FAILED) {
  // We got here first
  isCreator = 1;
} else {
  if (errno != EEXIST) uh_oh_goodbye();

  // We're not first.  Try again
  sem = sem_open("/the_sem", 0);
  if (sem == SEM_FAILED) uh_oh_goodbye();
}

注意:如果同步对象在共享内存中初始化,您可以在进程之间共享 pthread 互斥锁(以及匿名实时信号量)。 POSIX 共享内存实时扩展也允许shared memory to be named。然后在创建共享内存和初始化互斥体之间存在一些竞争,但在这种情况下,尝试调用 pthread_mutex_init() 应该会失败,除了比赛获胜者之外的所有人都使用 EBUSY。

【讨论】:

  • 我的意思是问 Android 的问题,但不幸的是,命名互斥锁似乎不存在。我见过的解决方案涉及使用类似于您的答案的 System V Semaphores。不幸的是,Android 没有包含包含这些 API 调用的头文件,因此这也不起作用。
猜你喜欢
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2011-09-11
  • 1970-01-01
相关资源
最近更新 更多