我认为只有异常(软件中断)是通过信号通知的。硬件中断的情况呢。
从哪里开始?有很多不同的情况。请记住,中断是调用 CPU 的硬件。中断本质上由“需要注意的硬件”和一个介于 0 到 255 之间的数字组成。信号相似但有 2 个参数:目标进程 ID 和一个 int(32 位或 64 位,取决于架构)。硬件中断总是在内核空间处理,而信号只是用户空间的东西。内核出于各种原因使用硬件中断。
与信号无关的硬件中断的一个示例是 VM 子系统。您知道在现代操作系统上,您可以分配比系统上实际存在的内存更多的内存。那么这是如何工作的呢?好吧,它通过利用硬件中断来工作。当您分配内存时,内核会记下它,但实际上根本不做任何事情。然后,当你尝试访问分配的内存时,cpu 会报错“但是这个内存不存在”,这会产生一个硬件中断。内核将查看它的注释,发现您确实请求了该内存,清除一些它有空闲的内存,并告诉 cpu 将该内存“映射”到预期的位置。之后,内核会在硬件中断发生之前的时间点恢复您的程序,这一次该进程将找到内存就好了。
多任务处理也是通过利用硬件中断来实现的。所有驱动程序通常通过解释中断来工作。
信号用于进程之间的通信。 linux 守护进程在 SIGHUP 上重新加载配置的常见行为将是非常“信号-y”的东西,受到各地系统管理员的喜爱和憎恨。例如,当您修改 apache 配置时,该过程不会自动开始使用新配置。您可能会终止并重新启动该过程,但这意味着您的 http 服务器将在 4-5 秒内停止运行。因此,您可能会“killall -HUP apache”。这将在 apache 进程中调用一个子程序,这将使它重新读取它的配置文件。
进程挂起是通过信号 (ctrl-z)、进程中断 (ctrl-c)、进程退出 (ctrl-)、终端断开 (sighup) 来实现的……更完整的列表可以在这里找到:@987654321 @。
一个结论可能是它们有点相似,但它们在不同的级别上运行:硬件中断是,嗯,硬件需要关注,而最低级别的软件需要。通常内核处理所有硬件,并且通知进程在某种程度上独立于硬件中断。对于许多信号,提供了默认处理(例如 ctrl-z、ctrl-c、...),对于其他信号,实现非常依赖于应用程序(例如 SIGHUP)。
说到信号,这些只是软件定义的。他们做任何你想让他们做的事,而且 linux 提供了方便的方法来调用这些子例程。在某些情况下,内核可能会调用信号例程(例如 SIGSEGV、SIGCHILD...),但它几乎不涉及硬件。它们只是在应用程序中触发特定例程的一种便捷方式。
曾经有一个特殊情况:“OS”中断,在 DOS 21h 中。这不再使用(尽管仍然有效),但想法是这样的。程序可以触发特定的中断来要求内核执行特定的操作。系统调用的操作(打开文件,关闭套接字,你有什么)。正如我所说,有趣,但不再真正使用。
信号的各种来源是什么?在我看来,内核始终是信号的来源。(用于 IPC 时除外)
信号来自进程本身 (SIGABRT)、内核 (SIGSEGV, ...) 或来自其他进程,例如 shell (ctrl-z, ctrl-c, ctrl-\, .. .) 或杀死。但是它们可以通过使用 kill libc 函数来自任何其他程序:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
信号处理程序和 ISR 的区别?
主要区别在于 ISR 存在于内核空间中,并且必须考虑到整个计算机在执行过程中会被冻结。这意味着他们可以中断任何进程,以及内核中的任何内容。他们还“阻止了世界”。在处理中断时,不会发生其他任何事情。因此,如果中断处理程序等待某些东西,机器就会冻结。如果中断处理程序进入循环,您唯一的选择是重新启动机器。
ISR 真的很难做到正确。关于它们有很多理论,在 linux 上它们有上半部分和下半部分,具有各种优先级处理、特殊内存分配……这是一个雷区。在 ISR 中朝着错误的方向迈出一步会杀死机器。 ISR 中的错误会导致数据丢失,甚至可能导致彻底的硬件故障。事实上,从经验来看,仅仅怀疑您可能计划在 ISR 中做错事会立即导致完全不可预测的机器行为。
您不能在 ISR 中使用任何内核工具。打开一个文件,忘记它。分配内存,算了。调用内核的任何其他部分,忘记它(有一些,但只有少数例外)。名单还在继续。
信号只是特定进程中被调用的函数。信号可能会阻塞(例如 ctrl-z),这将阻止进程继续进行,但例如您的 shell 会话仍会响应。该过程需要考虑到程序的任何部分当然可能已被中断,但它仍然是正常的用户空间。你可以阻塞,你可以循环,你可以打开文件,分配内存,......任何你想要的。
信号阻塞和中断屏蔽的区别?
它们非常相似。除了信号阻塞是在每个进程的基础上完成的。在这两种情况下都有不可阻塞的信号,并且有一个 NMI(不可屏蔽中断)(两者都表示严重错误)。
最后,信号和中断正在向内核或特定进程发送一个数字。信号阻塞和中断屏蔽只是意味着告诉系统忽略特定的数字。
一个区别是中断屏蔽是在硬件中实现的。