如何信号工作的? [英] How do signals work?

查看:100
本文介绍了如何信号工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何信号UNIX的作品?我通过W.R.Stevens所著去,但无法理解。请帮我。

How do signals works in unix? I went through W.R. Stevens but was unable to understand. Please help me.

推荐答案

下面的解释并不准确,这个作品不同的系统(甚至在不同的硬件相同操作系统的某些部分)之间的区别几个方面,但我认为,它通常是足够的你来满足你的好奇心足够使用它们。大多数人开始使用编程信号,甚至没有这个水平的认识,但在此之前我使用它们得到了舒服,我想了解他们。

The explanation below is not exact, and several aspects of how this works differ between different systems (and maybe even the same OS on different hardware for some portions), but I think that it is generally good enough for you to satisfy your curiosity enough to use them. Most people start using signals in programming without even this level of understanding, but before I got comfortable using them I wanted to understand them.

操作系统内核有要求其具有有关该过程数据的每个进程运行一个过程控制块的数据结构。这可以通过进程ID(PID)被抬起头来,包括信号操作的表,并挂起信号。

The OS kernel has a data structure called a process control block for each process running which has data about that process. This can be looked up by the process id (PID) and included a table of signal actions and pending signals.

当一个信号被发送到一个进程OS内核将查找该进程的进程控制块,并检查该信号动作表以找到特定信号的操作被发送。如果信号动作值 SIG_IGN 然后将新的信号是由内核忘记了。如果信号动作值 SIG_DFL 那么内核查找在另一个表和preforms这一行动的信号默认的信号处理操作。如果值别的随后被假定为正被发送的信号,该信号应该被称为过程中的一功能地址。为值 SIG_IGN SIG_DFL 是转换为函数指针的值不是一个进程的地址空间中的有效地址数(如0和1,这两者都是在0页,这是从未映射到一个进程)。

When a signal is sent to a process the OS kernel will look up that process's process control block and examines the signal action table to locate the action for the particular signal being sent. If the signal action value is SIG_IGN then the new signal is forgotten about by the kernel. If the signal action value is SIG_DFL then the kernel looks up the default signal handling action for that signal in another table and preforms that action. If the values are anything else then that is assumed to be a function address within the process that the signal is being sent to which should be called. The values for SIG_IGN and SIG_DFL are numbers cast to function pointers whose values are not valid addresses within a process's address space (such as 0 and 1, which are both in page 0, which is never mapped into a process).

如果信号处理函数是由程序注册(信号动作值既不SIG_IGN或SIG_DFL),那么在未决信号表中的条目由该信号和处理标记为准备运行(它可能有一直在等待的东西,喜欢成为可用数据调用,等待一个信号,或者其他一些事情)。

If a signal handling function were registered by the process (the signal action value was neither SIG_IGN or SIG_DFL) then an entry in the pending signal table is made for that signal and that process is marked as ready to RUN (it may have been waiting on something, like data to become available for a call to read, waiting for a signal, or several other things).

现在,这一进程在运行操作系统内核将首先添加一些数据到堆栈,因此它看上去很像过程本身刚刚称为信号处理程序修改该进程的指令指针的下一次。这是不完全正确的,实际上偏离足以从实际发生的事情,我会更多的谈论它在一点点。

Now the next time that the process is run the OS kernel will first add some data to the stack and changes the instruction pointer for that process so that it looks almost like the process itself has just called the signal handler. This is not entirely correct and actually deviates enough from what actually happens that I'll talk about it more in a little bit.

信号处理函数可以做任何它(这就是它被称为代表过程的一部分,所以它与有关方案应与信号做什么的知识写的)。当信号处理程序返回然后定期code的过程开始再次执行。 (再次,不准确,但更多的是下一个)

The signal handler function can do whatever it does (it is part of the process that it was called on behalf of, so it was written with knowledge about what that program should do with that signal). When the signal handler returns then the regular code for the process begins executing again. (again, not accurate, but more on that next)

好吧,上面应该给你的信号是如何传递到进程$​​ P $ ptty好主意。我认为这个的 pretty 的的的想法的才能掌握充分的想法,其中包括一些更复杂的东西需要的版本。

Ok, the above should have given you a pretty good idea of how signals are delivered to a process. I think that this pretty good idea version is needed before you can grasp the full idea, which includes some more complicated stuff.

很多时候,操作系统内核需要知道,当信号处理程序返回。这是因为信号处理需要一个参数(这可能需要堆栈空间),可以阻止从信号处理程序的执行过程中被传递两次相同的信号,和/或有一个信号被交付后,系统调用重新启动。为了实现比堆栈和指令指针的变化这多一点点。

Very often the OS kernel needs to know when a signal handler returns. This is because signal handlers take an argument (which may require stack space), you can block the same signal from being delivered twice during the execution of the signal handler, and/or have system calls restarted after a signal is delivered. To accomplish this a little bit more than stack and instruction pointer changes.

有什么要发生的是,内核需要做的过程中告诉它,它已经完成执行信号处理函数。这可以通过映射的RAM到进程的地址空间的部分,其中包含code,使这个系统调用,使返回地址的信号处理函数来完成(在堆栈顶部的值时,此功能并开始运行)是这个地址code。我认为这是它是如何在Linux下(至少更新的版本)来完成。另一种方式来做到这一点(我不知道这样做,但它可能是)将不使返回地址信号处理函数是一个无效的地址(如NULL),这将导致在大多数系统中断,这将再次给操作系统内核控制。没关系一大堆如何发生,但内核重新获得控制修复堆栈和知道,信号处理程序已完成。

What has to happen is that the kernel needs to make the process tell it that it has finished executing the signal handler function. This may be done by mapping a section of RAM into the process's address space which contains code to make this system call and making the return address for the signal handler function (the top value on the stack when this function started running) be the address of this code. I think that this is how it is done in Linux (at least newer versions). Another way to accomplish this (I don't know if this is done, but it could be) would be do make the return address for the signal handler function be an invalid address (such as NULL) which would cause an interrupt on most systems, which would give the OS kernel control again. It doesn't matter a whole lot how this happens, but the kernel has to get control again to fix up the stack and know that the signal handler has completed.

这是Linux内核做了页面映射到这个过程中,但实际的系统调用登记信号处理(什么的sigaction的通话的)需要一个参数sa_restore参数,这是一个地址应作为从信号处理函数的返回地址,内核只是确保它放在那里。在这个地址的code发布的完成的系统调用( sigreturn )和内核知道该信号处理程序已完成。

that the Linux kernel does map a page into the process for this, but that the actual system call for registering signal handlers (what sigaction calls ) takes a parameter sa_restore parameter, which is an address that should be used as the return address from the signal handler, and the kernel just makes sure that it is put there. The code at this address issues the I'm done system call (sigreturn)and the kernel knows that the signal handler has finished.

我主要假设你知道信号是如何在第一时间产生的。 OS可以代表一个进程生成它们由于东西发生,像一个计时器到期,子进程垂死,访问​​存储器,它不应该被访问,或发出一个指令,它应不(或者指示不存在或一个是特权),或许多其他的事情。计时器的情况是功能与其他有所不同,因为在过程没有运行可能发生,所以更像是与系统调用发送的信号。为代表时发生中断,因为当前的过程是做错事这些产生当前进程发送的非计时器相关信号。此中断给内核控制(就像一个系统调用)和内核生成要传递到当前处理的信号。

I'm mostly assuming that you know how signals are generated in the first place. The OS can generate them on behalf of a process due to something happening, like a timer expiring, a child process dying, accessing memory that it should not be accessing, or issuing an instruction that it should not (either an instruction that does not exist or one that is privileged), or many other things. The timer case is functionally a little different from the others because it may occur when the process is not running, and so is more like the signals sent with the kill system call. For the non-timer related signals sent on behalf of the current process these are generated when an interrupt occurs because the current process is doing something wrong. This interrupt gives the kernel control (just like a system call) and the kernel generates the signal to be delivered to the current process.

这篇关于如何信号工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆