当将信号量减为零的进程崩溃时,如何恢复信号量?

2024-11-01 08:41:00
admin
原创
38
摘要:问题描述:我有多个使用 g++ 编译的应用程序,在 Ubuntu 中运行。我使用命名信号量来协调不同的进程。除以下情况外,所有工作都正常:如果其中一个进程调用sem_wait()或sem_timedwait()减少信号量,然后在有机会调用之前崩溃或被杀死-9 sem_post(),那么从那一刻起,命名信号量就...

问题描述:

我有多个使用 g++ 编译的应用程序,在 Ubuntu 中运行。我使用命名信号量来协调不同的进程。

以下情况外,所有工作都正常:如果其中一个进程调用sem_wait()sem_timedwait()减少信号量,然后在有机会调用之前崩溃或被杀死-9 sem_post(),那么从那一刻起,命名信号量就“不可用”。

我所说的“不可用”是指信号量计数现在为零,而应该将其增加回 1 的进程已经死亡或被终止。

我找不到sem_*()可以告诉我上次减少的进程已崩溃的 API。

我是否在某处遗漏了 API?

下面是我打开命名信号量的方法:

sem_t *sem = sem_open( "/testing",
    O_CREAT     |   // create the semaphore if it does not already exist
    O_CLOEXEC   ,   // close on execute
    S_IRWXU     |   // permissions:  user
    S_IRWXG     |   // permissions:  group
    S_IRWXO     ,   // permissions:  other
    1           );  // initial value of the semaphore

以下是我减少它的方法:

struct timespec timeout = { 0, 0 };
clock_gettime( CLOCK_REALTIME, &timeout );
timeout.tv_sec += 5;

if ( sem_timedwait( sem, &timeout ) )
{
    throw "timeout while waiting for semaphore";
}

解决方案 1:

事实证明,没有办法可靠地恢复信号量。当然,任何人都可以post_sem()对命名信号量进行操作,使计数再次超过零,但如何判断何时需要进行这种恢复?提供的 API 太有限,无法以任何方式指示何时发生了这种情况。

请注意,还有 ipc 工具可用——常用工具ipcmkipcrmipcs仅适用于过时的 SysV 信号量。它们特别不适用于新的 POSIX 信号量。

但似乎还有其他东西可用于锁定事物,当应用程序以一种无法被信号处理程序捕获的方式死亡时,操作系统会自动释放这些事物。两个例子:绑定到特定端口的监听套接字,或特定文件上的锁定。

我认为文件上的锁定是我需要的解决方案。因此,我没有使用sem_wait()andsem_post()调用,而是使用:

lockf( fd, F_LOCK, 0 )

lockf( fd, F_ULOCK, 0 )

当应用程序以任何方式退出时,文件将自动关闭,同时释放文件锁。然后等待“信号量”的其他客户端应用程序就可以自由地按预期继续运行。

谢谢大家的帮助。


更新:

12 年后,我认为我应该指出 posix 互斥锁确实具有“健壮”属性。这样,如果互斥锁的所有者被杀死或退出,下一个锁定互斥锁的用户将获得非错误返回值EOWNERDEAD,从而允许恢复互斥锁。这将使其类似于文件和套接字锁定解决方案。查看pthread_mutexattr_setrobust()pthread_mutex_consistent()了解详细信息。感谢 Reinier Torenbeek 提供的提示。

解决方案 2:

使用锁定文件而不是信号量,与 @Stéphane 的解决方案非常相似,但没有 flock() 调用。您只需使用独占锁打开文件即可:

//call to open() will block until it can obtain an exclusive lock on the file.
errno = 0;
int fd = open("/tmp/.lockfile", 
    O_CREAT | //create the file if it's not present.
    O_WRONLY | //only need write access for the internal locking semantics.
    O_EXLOCK, //use an exclusive lock when opening the file.
    S_IRUSR | S_IWUSR); //permissions on the file, 600 here.

if (fd == -1) {
    perror("open() failed");
    exit(EXIT_FAILURE);
}

printf("Entered critical section.
");
//Do "critical" stuff here.
//...

//exit the critical section
errno = 0;
if (close(fd) == -1) {
    perror("close() failed");
    exit(EXIT_FAILURE);
}

printf("Exited critical section.
");

解决方案 3:

这是管理信号量时的一个典型问题。一些程序使用单个进程来管理信号量的初始化/删除。通常,此进程只执行此操作,不执行其他任何操作。您的其他应用程序可以等到信号量可用。我见过使用 SYSV 类型 API 完成此操作,但未见过使用 POSIX 完成此操作。与“ Duck ”提到的类似,在 semop() 调用中使用 SEM_UNDO 标志。

但是,根据您提供的信息,我建议您不要使用信号量。特别是当您的进程有被终止或崩溃的危险时。尝试使用操作系统会自动为您清理的东西。

解决方案 4:

您需要仔细检查,但我相信 sem_post 可以从信号处理程序调用。如果您能够捕捉到导致进程停止的一些情况,这可能会有所帮助。

与互斥锁不同,任何进程或线程(具有权限)都可以向信号量发送消息。您可以编写一个简单的实用程序来重置它。假设您知道系统何时死锁。您可以关闭它并运行实用程序。

信号电话通常列在 /dev/shm 下,您可以将其删除。

SysV 信号量更适合这种情况。您可以指定 SEM_UNDO,这样系统将撤消进程对信号量所做的更改(如果进程终止)。它们还可以告诉您更改信号量的最后一个进程 ID。

解决方案 5:

您应该能够使用 从 shell 中找到它lsof。那么您可以删除它吗?

更新

啊,是的...man -k semaphore来救援。

似乎您可以使用ipcrm来摆脱信号量。看来您不是第一个遇到这个问题的人。

解决方案 6:

如果该进程被终止,那么就没有任何直接的方法来确定它已经消失。

您可以对所有信号量进行某种定期完整性检查 - 使用semctl (cmd=GETPID) 查找最后一个接触您描述状态的每个信号量的进程的 PID,然后检查该进程是否仍然存在。如果不存在,请执行清理。

解决方案 7:

lsof如果使用命名信号量,那么您可以使用类似于或中使用的算法fuser

请考虑以下几点:

1.每个命名的 POSIX 信号量通常在以下路径下在 tmpfs 文件系统中创建一个文件:

/dev/shm/

2.linux中每个进程都有一个map_files,位于路径下:

/proc/[PID]/map_files/

这些映射文件显示了进程内存的哪一部分映射到什么!

因此,使用这些步骤,您可以找到命名的信号量是否仍由另一个进程打开:

1-(可选)查找命名信号量的确切路径(如果它不在/dev/shm

  • 首先在新进程中打开命名信号量,并将结果赋给一个指针

  • 找到内存中指针的地址位置(通常将指针的地址转换为整数类型)并将其转换为十六进制(即结果:)0xffff1234数字,然后使用此路径:

/proc/self/map_files/ffff1234-*

应该只有一个文件满足此条件。

  • 获取该文件的符号链接目标。它是命名信号量的完整路径。

2- 遍历所有进程以查找其符号链接标记与指定信号量的完整路径匹配的映射文件。如果存在,则表示该信号量正在实际使用中,但如果没有,则可以安全地取消链接指定信号量并重新打开它以供使用。

更新

在步骤 2 中,当遍历所有进程时,最好不要遍历文件夹 中的所有文件map_file,而是使用文件/proc/[PID]/maps并在其中搜索命名信号量文件(即:)的完整路径/dev/shm/sem_xyz。在这种方法中,即使其他一些程序取消了命名信号量的链接,但该信号量仍在其他进程中使用,它仍然可以被找到,但其文件路径末尾会附加一个“(已删除)”标志。

解决方案 8:

sem_unlink()只需在 之后立即执行sem_open()。Linux 将在所有进程关闭资源后删除,其中包括内部关闭。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用