简单的 Linux 信号处理

2024-01-26

I have a program that creates many threads and runs until either power is shutdown to the embedded computer, or the user uses kill or ctrlc to terminate the process.

这是一些代码以及 main() 的外观。

static int terminate = 0;  // does this need to be volatile?

static void sighandler(int signum) { terminate = 1; }

int main() {
  signal(SIGINT, sighandler);
  // ...
  // create objects, spawn threads + allocate dynamic memory
  // ...
  while (!terminate) sleep(2);
  // ...
  // clean up memory, close threads, etc.
  // ...
  signal(SIGINT, SIG_DFL);  // is this necessary?
}

我想知道一些事情:

  1. 是否需要任何信号处理?
    我在这个帖子中读到“Linux C 捕获终止信号以优雅终止” https://stackoverflow.com/questions/7376228/linux-c-catching-kill-signal-for-graceful-termination,显然操作系统会为我处理清理工作。 因此,我可以用无限循环替换信号处理程序,让操作系统优雅地退出线程、取消分配内存等吗?

  2. 关于干净终止还有其他我需要关注的信号吗?这个线程“SIGINT 与其他终止信号有何关系?” https://stackoverflow.com/questions/4042201/how-does-sigint-relate-to-the-other-termination-signals,列出我可能关心的所有信号很有用,但实际需要处理多少信号?

  3. 我的示例中的终止变量是否必须是易失性的?我见过很多例子,其中这个变量是易失性的,而其他例子则不是。

  4. 我读过signal()现已弃用,并使用sigaction()。有没有什么很好的例子来展示如何从以前的转换signal()称呼?我在必须创建/传递的新结构以及它们如何组合在一起方面遇到了麻烦。

  5. 第二次致电是signal()必要的?
    有没有类似的事情我需要关心sigaction()?

To be clear, all I'm trying to accomplish to to have my: main loop run until either ctrlc or power is disconnected or something really bad happens.


[Q-3]是否terminate我的示例中的变量必须是volatile?我有 见过很多这个变量是易失性的例子,还有一些例子 它不是。

旗帜terminate应该volatile sig_atomic_t:

因为处理函数可以异步调用。也就是说,处理程序可能会在程序中的任何点被调用,这是不可预测的。如果两个信号在很短的时间间隔内到达,则一个处理程序可以在另一个处理程序内运行。声明被认为是更好的做法volatile sig_atomic_t,这种类型总是以原子方式访问,避免中断访问变量的不确定性。volatile告诉编译器不要优化并将其放入寄存器。 (读:原子数据访问和信号处理 http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC358详细说明)。
再来一张参考资料:24.4.7 原子数据访问和信号处理 http://www.gnu.org/software/libc/manual/html_node/Atomic-Data-Access.html#Atomic-Data-Access。 此外,7.14.1.1-5 中的 C11 标准表明,只有volatile sig_atomic_t可以从信号处理程序访问(访问其他信号处理程序具有未定义的行为)。

[Q-4]我读过signal()现已弃用,并使用sigaction()。是 有任何非常好的例子来展示如何从 以前的signal()称呼?我对新结构遇到了麻烦 我必须创建/传递以及它们如何组合在一起。

下面的示例(以及评论中的链接)可能会有所帮助:

// 1. Prepare struct 
struct sigaction sa;
sa.sa_handler =  sighandler;

// 2. To restart functions if interrupted by handler (as handlers called asynchronously)
sa.sa_flags = SA_RESTART; 

// 3. Set zero 
sigemptyset(&sa.sa_mask);

/* 3b. 
 // uncomment if you wants to block 
 // some signals while one is executing. 
sigaddset( &sa.sa_mask, SIGINT );
*/ 

// 4. Register signals 
sigaction( SIGINT, &sa, NULL );

参考:

  1. Linux 编程入门,第四版 http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC358:在这本书中,您的代码的解释是sigaction()“第 11 章:进程和信号”中有很好的说明。
  2. The 签名操作文档 http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/s/sigaction.html,包括一个示例(快速学习)。
  3. The GNU C Library: Signal Handling http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC330
    *I started from 1 http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC358, Presently I am reading 3 http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC358 GNU-library

[Q-5]第二次致电是signal()必要的?有没有类似的事情我需要关心sigaction()?

我不清楚为什么在程序终止之前将其设置为默认操作。我想下面这段话会给你答案:

处理信号 http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr1/z1ling.htm

对 signal 的调用仅建立信号处理one信号的发生。在调用信号处理函数之前,库会重置信号,以便在再次发生相同信号时执行默认操作。重置信号处理有助于防止无限循环,例如,如果在信号处理程序中执行的操作再次引发相同的信号。如果您希望每次发生信号时都将处理程序用于信号,则必须在处理程序中调用 signal 来恢复它。您应该谨慎恢复信号处理。例如,如果您不断恢复SIGINT处理,您可能会失去中断和终止程序的能力。

The signal()函数仅定义下一个接收到的信号的处理程序,之后恢复默认处理程序。所以信号处理程序需要调用signal() 如果程序需要继续使用非默认处理程序处理信号。

阅读讨论以供进一步参考:何时重新启用信号处理程序 http://cboard.cprogramming.com/linux-programming/150239-when-re-enable-signal-handlers.html.

[Q-1a]是否需要任何信号处理?

是的,Linux 会为你做清理工作。例如,如果您不关闭文件或套接字,Linux 将在进程终止后进行清理。但Linux可能不需要立即执行清理,可能需要一些时间(可能是为了保持系统高性能或其他一些问题)。例如,如果您不关闭 tcp-socket 并且程序终止,则内核不会立即关闭套接字以确保所有数据已传输,如果可能,TCP 会保证传输。

[Q-1b]因此,我可以用无限循环替换信号处理程序,让操作系统优雅地退出线程、取消分配内存等吗?

不,操作系统仅在程序终止后执行清理工作。当进程执行时,分配给该进程的资源不会被操作系统占用。 (操作系统无法知道你的进程是否处于无限循环中 -这是一个无法解决的问题 https://en.wikipedia.org/wiki/Halting_problem)。如果您希望在进程终止后操作系统为您执行清理操作,那么您不需要处理信号(即使您的进程被信号异常终止)。

[Q] All I'm trying to accomplish to to have my: main loop run until either ctrlc or power is disconnected or something really bad happens.

不,有一个限制!您无法捕获所有信号。有些信号无法捕获,例如SIGKILL and SIGSTOP两者都是终止信号。引用一则:

— 宏:intSIGKILL http://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html

The SIGKILL信号用于导致程序立即终止。它无法处理或忽略,因此总是致命的。也是not可以阻止该信号。

所以你不能使不可中断的程序(不间断的程序) https://stackoverflow.com/questions/12437648/uninterruptable-process-in-windowsor-linux!

I am not sure but may be you can do something like this in Windows systems: by writing TSRs (some sort of kernel-mode hooking). I remember from my thesis time that some viruses couldn't be terminated even from task manager but I also believe that they trick user by admin permissions.

我希望这个答案能帮助你。

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

简单的 Linux 信号处理 的相关文章

  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • Linux 堆栈大小

    我正在寻找 Linux 内核中堆栈的良好描述 但我发现找到任何有用的东西出奇地困难 我知道大多数系统的堆栈限制为 4k 而其他系统则限制为 8k 我假设每个内核线程 下半部分都有自己的堆栈 我还听说 如果中断发生 它会使用当前线程的堆栈 但
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • HTTP 直播 MPEG TS 段

    我使用 FFMPEG 和免费分段器 Carson Mcdonald s 来生成我的 ts 片段 然后将其保存到网络服务器并通过播放 m3u8 来使用 Quicktime 进行播放 如果我有段 1 2 3 4 和另一个包含段 1 2 3 4
  • 解释一下莫名其妙的死锁

    首先 我不明白我怎么能得到any根本没有死锁 因为我没有使用显式锁定 所以只涉及一个表 每个进程都有一个单独的进程来插入 选择和更新行 一次只插入或更新一行 并且每个进程很少 也许一分钟一次 完全运行 这是一个电子邮件队列 CREATE T
  • 从 Visual Studio 在 Linux docker 容器中调试 nunit 测试

    我正在尝试更改我们的 NET Core 3 0 应用程序以在 Linux 容器中运行 我已经到了可以在容器内恢复和构建的地步 但测试失败了 这是预期的 该应用程序中的某些内容仅适用于 Windows 计算机 我想从 Windows 上的 V
  • 配置 Play 1.x/JPA 以顺序生成实体 ID?

    强制 Play JPA 使实体 ID 连续的最佳方法是什么 他们不是 https stackoverflow com questions 9771532 are jpa ids sequential 一种想法是将 play db jpa M
  • 谁能告诉我当我尝试添加syncfusion_flutter_pdfviewer包时flutter中的这个错误是什么

    当我在 yaml 文件中添加syncfusion flutter pdfviewer 包时 出现以下错误 谁能告诉我那个错误状态是什么 C src flutter pub cache hosted pub dartlang org sync
  • 如何在Docker中使用“绑定挂载”

    运行此命令后 我在日志中收到错误 docker run d p 3000 80 name Feedback app v 反馈 app feedback v WorkSpace d data volumes 03 adj node code
  • 如何在Linux命令行中运行jar文件

    如何将类路径设置为当前目录并运行名为的 jar 文件load jar通过提供参数作为当前目录中的内容load 2从 Linux 命令行 我确实尝试按如下方式运行该 jar 但它从其他目录执行类 java cp load jar CLASSP
  • 通过多线程访问文件

    我想通过10个线程访问一个大文件 文件大小可能从30MB到1GB不等 然后通过10个线程处理文件中的每一行并将它们写入另一个文件 如果我只使用一个线程访问IO 其他线程就会被阻塞 该处理花费的时间几乎相当于从文件系统读取一行代码 还有一个限
  • Python 如何实现其类型对象,即类型类型始终是类型?

    我知道Python中的所有东西都是一个对象 并且这些对象的 类型 或类 是 类型 另外 类型的类型也是类型本身 正如解释得很好here http www cafepy com article python types and objects
  • Whatsapp://send?text 将字符串从“&”字符剪切到末尾? [复制]

    这个问题在这里已经有答案了 我正在尝试添加可在 WhatsApp 中共享的链接 例如 whatsapp send text http www example com products women dresses sessionid 3456
  • 为什么调用 DataTable().draw() 时 columns.render 不执行?

    我很困惑为什么列 渲染 https datatables net reference option columns render不包含在执行管道中数据表 draw https datatables net reference api dra
  • 如何在 GWT 中深度复制任意对象?

    我有一个标记为可序列化的任意对象 它有各种可变的子对象 表示货币金额 集合等 我希望能够克隆这个对象 这样如果用户修改它然后恢复他们的操作 我可以用新的克隆替换该克隆 这意味着我需要深层复制 因为我不希望用户对原始对象上出现的子对象进行更改
  • UNIQUE 约束失败:auth_user.username

    我试图将名字和姓氏直接从 Facebook API 存储到用户身份验证模型 使用 FacebookProfile 模型扩展 包含 webpull id 和year formed 模型 py class FacebookProfile mod
  • 使用 PHP 或 Javascript 检查 iOS 版本是否为 3.0 或更高版本

    我需要检查访问我网站的 iOS 设备是否安装了 iOS 3 0 或更高版本 我可以这样做吗 如果您想检查哪些浏览器 移动设备正在访问您的网站 那么答案是您可以使用读取 userAgent 字符串并搜索操作系统和号码 例如 Mozilla 5
  • django 中带有 django 表单的预选复选框

    我试图在中显示预先选定的复选框Django option forms BooleanField required False initial True but the checkbox显示已检查 我正在使用django 1 3 beta 我
  • 我已经注册了应用程序 ID,但仍然显示您没有适用于 iOS 应用程序的合格捆绑包 ID。在这里注册一个

    我已经注册了App ID 使用通配符和不使用通配符都有 这不是我第一次创建应用程序 ID 并将其提交到应用程序商店 但是在developer apple com上注册appID后 当我尝试在 itunesconnect apple com
  • 在Python中写入打开的文件时的分割函数[重复]

    这个问题在这里已经有答案了 所以我有一个程序 我应该在其中获取一个外部文件 用 python 打开它 然后分隔每个单词和每个标点符号 包括逗号 撇号和句号 然后我应该将该文件保存为文本中每个单词和标点符号出现时的整数位置 例如 我喜欢编码
  • 为什么 Window.Close 事件会传播?

    我遇到了一个奇怪的情况Close子窗口的事件传播到父窗口并导致其关闭 我做了一个最小的例子 如下所示 For TestWindow除了VS生成的默认WPF窗口之外什么都没有 and in App xaml cs我覆盖OnStartup事件并
  • 打包(类型擦除)随机数生成器

    C 11 std 库有几个随机数生成器 RNG 每个都实现了这个概念统一随机数生成器 http en cppreference com w cpp concept UniformRandomNumberGenerator 然后可以将它们用作
  • 简单的 Linux 信号处理

    I have a program that creates many threads and runs until either power is shutdown to the embedded computer or the user