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

2024-01-20

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

一切正常except在以下情况下:如果其中一个进程调用sem_wait() or sem_timedwait()减少信号量,然后在有机会调用之前崩溃或被杀死 -9sem_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";
}

事实证明,没有办法可靠地恢复信号量。当然,任何人都可以post_sem()到指定的信号量以使计数再次增加到零以上,但是如何判断何时需要这样的恢复?提供的 API 太有限,并且没有以任何方式指示这种情况何时发生。

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

但看起来还有其他东西可以用来锁定东西,当应用程序以信号处理程序无法捕获的方式终止时,操作系统会自动释放这些东西。两个示例:绑定到特定端口的侦听套接字,或特定文件上的锁定。

我认为文件锁定是我需要的解决方案。所以而不是sem_wait() and sem_post()打电话,我正在使用:

lockf( fd, F_LOCK, 0 )

and

lockf( fd, F_ULOCK, 0 )

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

谢谢你们的帮助,伙计们。


UPDATE:

12 年后,我想我应该指出 posix 互斥体确实具有“鲁棒”属性。这样,如果互斥锁的所有者被杀死或退出,下一个锁定互斥锁的用户将获得非错误返回值EOWNERDEAD,允许恢复互斥锁。这将使其类似于文件和套接字锁定解决方案。抬头pthread_mutexattr_setrobust() and pthread_mutex_consistent()了解详情。谢谢 Reinier Torenbeek 的提示。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当将信号量递减至零的进程崩溃时,如何恢复信号量? 的相关文章

  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • Linux 上的 Pervasive ODBC 错误 [01000][unixODBC][驱动程序管理器]无法打开 lib '/usr/local/psql/lib/odbcci.so':找不到文件

    我正在尝试让 Pervasive v10 客户端 ODBC 在 Centos 6 上运行 据我所知 没有 64 位 ODBC 客户端 因此我必须使用 32 位客户端 我终于成功安装了它 但尝试使用时出现以下错误 isql v mydsn 0
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文
  • 使用 shell 脚本将行附加到 /etc/hosts 文件

    我有一个新的 Ubuntu 12 04 VPS 我正在尝试编写一个安装脚本来完成整个 LAMP 安装 我遇到问题的地方是在 etc hosts文件 我当前的主机文件如下所示 127 0 0 1 localhost Venus The fol
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • 丢弃限定符

    我不太确定我的问题是什么 它说 放弃限定符 我不知道为什么会发生这种情况 如果我删除const对于重载运算符 一切安好 有人可以帮我吗 practice on overloading operators on Time variables
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 如何使用waf构建共享库?

    我想使用构建一个共享库waf http code google com p waf 因为它看起来比 GNU 自动工具更容易 更简洁 到目前为止 我实际上有几个与我开始编写的 wscript 有关的问题 VERSION 0 0 1 APPNA
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • 错误:“rjags”的包或命名空间加载失败

    在终端的 conda 环境之一中 我能够成功安装包 rjags 但是 当我在该环境中运行 R 并运行库 rjags 时 出现以下错误 加载所需的包 coda 错误 rjags 的包或命名空间加载失败 rjags 的 loadNamespac
  • Linux 为一组进程保留一个处理器(动态)

    有没有办法将处理器排除在正常调度之外 也就是说 使用sched setaffinity我可以指示线程应该在哪个处理器上运行 但我正在寻找相反的情况 也就是说 我想从正常调度中排除给定的处理器 以便只有已明确调度的进程才能在那里运行 我还知道
  • linux下如何从文本文件中获取值

    我有一些文本格式的文件 xxx conf 我在这个文件中有一些文本 disablelog 1 当我使用 grep r disablelog oscam conf 输出是 disablelog 1 但我只需要值1 请问你有什么想法吗 一种方法
  • 如何在数据部分(RAM)中保留一定范围的内存并防止同一应用程序使用该内存的堆/堆栈?

    我想在 RAM 中保留 分配一定范围的内存 并且同一应用程序不应覆盖或使用该范围的内存进行堆 堆栈存储 如何在内存中分配一定范围的内存以防止堆栈 堆覆盖 我考虑过向应用程序本身添加 或分配 一个数组并保留内存 但它被编译器优化了 因为它在应
  • 这种文件锁定方法可以接受吗?

    我们有 10 个 Linux 机器 每周必须运行 100 个不同的任务 这些计算机主要在我们晚上在家时执行这些任务 我的一位同事正在开发一个项目 通过使用 Python 自动启动任务来优化运行时间 他的程序将读取任务列表 抓取一个打开的任务
  • 如何让 Node.js 作为后台进程运行并且永不死掉?

    我通过 putty SSH 连接到 linux 服务器 我尝试将其作为后台进程运行 如下所示 node server js 然而 2 5 小时后 终端变得不活动 进程终止 即使终端断开连接 我是否也可以使进程保持活动状态 Edit 1 事实
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读

随机推荐