Exceptional Control Flow(6)

A signal that has been sent but not yet received is called a pending signal.

At any point in time, there can be at most one pending signal of a particular type.

If a process has a pending signal of type k, then any subsequent signals of type k sent to that process are not queued; they are simply discarded.

A process can selectively block the receipt of certain signals.

When a signal is blocked, it can be delivered, but the resulting pending signal will not be received until the process unblocks the signal.

A pending signal is received at most once.

For each process, the kernel main- tains the set of pending signals in the pending bit vector,  and the set of blocked signals in the blocked bit vector.

The kernel sets bit k in pending whenever a sig- nal of type k is delivered and clears bit k in pending whenever a signal of type k is received.

Sending Signals

Unix systems provide a number of mechanisms for sending signals to processes. All of the mechanisms rely on the notion of a process group.

Process Groups

Every process belongs to exactly one process group, which is identified by a positive integer process group ID.

The getpgrp function returns the process group ID of the current process.

By default, a child process belongs to the same process group as its parent.

A process can change the process group of itself or another process by using the setpgid function:

The setpgid function changes the process group of process pid to pgid.

If pid is zero, the PID of the current process is used.

If pgid is zero, the PID of the process specified by pid is used for the process group ID.

For example, if process 15213 is the calling process, then

setpgid(0, 0);

creates a new process group whose process group ID is 15213, and adds process 15213 to this new group.

Sending Signals with the /bin/kill Program

The /bin/kill program sends an arbitrary signal to another process. For example, the command

sends signal 9 (SIGKILL) to process 15213.

unix> /bin/kill -9 15213

A negative PID causes the signal to be sent to every process in process group PID.

Sending Signals from the Keyboard

Unix shells use the abstraction of a job to represent the processes that are created as a result of evaluating a single command line.

At any point in time, there is at most one foreground job and zero or more background jobs.

The shell creates a separate process group for each job.

Typically, the process group ID is taken from one of the parent processes in the job.

Figure 8.27 shows a shell with one foreground job and two background jobs.

The parent process in the foreground job has a PID of 20 and a process group ID of 20.

The parent process has created two children, each of which are also members of process group 20.

Typing ctrl-c at the keyboard causes a SIGINT signal to be sent to the shell.

The shell catches the signal (see Section 8.5.3) and then sends a SIGINT to every process in the foreground process group.

Sending Signals with the kill Function

Processes send signals to other processes (including themselves) by calling the kill function.

If pid is greater than zero, then the kill function sends signal number sig to process pid.

If pid is less than zero, then kill sends signal sig to every process in process group abs(pid).

Sending Signals with the alarm Function

A process can send SIGALRM signals to itself by calling the alarm function.

The alarm function arranges for the kernel to send a SIGALRM signal to the calling process in secs seconds.

Receiving Signals

When the kernel is returning from an exception handler and is ready to pass control to process p, it checks the set of unblocked pending signals

(pending & ~blocked) for process p. If this set is empty (the usual case), then the kernel passes control to the next instruction (Inext) in the logical control flow of p.

However, if the set is nonempty, then the kernel chooses some signal k in the set (typically the smallest k) and forces p to receive signal k.

The receipt of the signal triggers some action by the process.

Once the process completes the action, then control passes back to the next instruction (Inext ) in the logical control flow of p.

Each signal type has a predefined default action, which is one of the following:

(1) The process terminates.

(2) The process terminates and dumps core.

(3) The process stops until restarted by a SIGCONT signal.

(4) The process ignores the signal.

A process can modify the default action associated with a signal by using the signal function:

The signal function can change the action associated with a signal signum in one of three ways:

(1) If handler is SIG_IGN, then signals of type signum are ignored.

(2) If handler is SIG_DFL, then the action for signals of type signum reverts to the default action.

(3) Otherwise, handler is the address of a user-defined function, called a signal handler, that will be called whenever the process receives a signal of type signum.

When a process catches a signal of type k, the handler installed for signal k is invoked with a single integer argument set to k.

This argument allows the same handler function to catch different types of signals.

Signal handlers are yet another example of concurrency in a computer system.

The execution of the signal handler interrupts the execution of the main C routine, akin to the way that a low-level exception handler interrupts the control flow of the current application program.

Since the logical control flow of the signal handler overlaps the logical control flow of the main routine, the signal handler and the main routine run concurrently.

Signal Handling Issues

...However, subtle issues arise when a program catches multiple signals.

(1) Pending signals are blocked. Unix signal handlers typically block pending signals of the type currently being processed by the handler.

For example, suppose a process has caught a SIGINT signal and is currently running its SIGINT handler.

If another SIGINT signal is sent to the process, then the SIGINT will become pending, but will not be received until after the handler returns.

(2) Pending signals are not queued. There can be at most one pending signal of any particular type.

Thus, if two signals of type k are sent to a destination process while signal k is blocked because the destination process is currently executing a handler for signal k,

then the second signal is simply discarded; it is not queued. The key idea is that the existence of a pending signal merely indicates that at least one signal has arrived.

(3) System calls can be interrupted. System calls such as read, wait, and accept that can potentially block the process for a long period of time are called slow system calls.

On some systems, slow system calls that are interrupted when a handler catches a signal do not resume when the signal handler returns,

but instead return immediately to the user with an error condition and errno set to EINTR.

原文地址:https://www.cnblogs.com/geeklove01/p/9264938.html

时间: 2024-09-30 04:44:49

Exceptional Control Flow(6)的相关文章

《CS:APP》 chapter 8 Exceptional Control Flow 笔记

Exceptional Control Flow The program counter assumes a sequence of values a0,a1,...,an?1 where each ak is the address of some corresponding instruction Ik. Each transition from ak to ak +1 is called a control transfer. A sequence of such control tran

《CS:APP》 chapter 8 Exceptional Control Flow 注意事项

Exceptional Control Flow The program counter assumes a sequence of values a0,a1,...,an?1 where each ak is the address of some corresponding instruction Ik. Each transition from ak to ak +1 is called a control transfer. A sequence of such control tran

Exceptional Control Flow(1)

different levels of ECF: In general, we refer to these abrupt changes as exceptional control flow (ECF). Exceptional control flow occurs at all levels of a computer system. For example, at the hardware level, events detected by the hardware trigger a

Exceptional C++: [Item 47. Control Flow] [条款47 控制流]

条款47控制流 难度:6 你到底有多了解C++代码的执行顺序呢?通过这个问题来测试一下你的知识. "恶魔藏在细节里."尽量指出下面(人为)代码的问题,请集中在控制流相关的问题上. #include <cassert> #include <iostream> #include <typeinfo> #include <string> using namespace std; // The following lines come from

Conditionals and Control Flow

Part 1: if and else Statements 1. Comparisons operators > Greater than < Less than <= Less than or equal to >= Greater than or equal to == Equal to != Not equal to 2. if Statements Now let's see how we can use comparisons to ask yes or no ques

Control Flow

[Control Flow] 1.for loop中的元素可以省略: 2.for initializer中的变量只能在循环内使用. 3.if.else if.else的用法: 最后一个else可选. 4.switch用法: 5.range match: 6.tuple作为case: 7.value绑定: 8.使用where来增加条件限制: 9.fallthrough关键字: 9.label statement用于for或while的前面,当多个for或while嵌套时,常常需要指跳转到哪: Co

关于Control flow

1.一个package包含一个control flow并且一个或多个data flow. (这个项目叫做 Integration services project,提供了三种不同类型的control flow 元件) 1.1 containers(provide structures in packages) 1.2 tasks(provide functionality) 1.3 precedence constraints (connect the executables, containe

The Swift Programming Language-官方教程精译Swift(6)控制流--Control Flow

Swift提供了类似C语言的流程控制结构,包括可以多次执行任务的for和while循环,基于特定条件选择执行不同代码分支的if和switch语句,还有控制流程跳转到其他代码的break和continue语句. 除了C里面传统的 for 条件递增循环,Swift 还增加了 for-in 循环,用来更简单地遍历数组(array),字典(dictionary),范围(range),字符串(string)和其他序列类型. Swift 的 switch 语句比 C 语言中更加强大.在 C 语言中,如果某个

SSIS的 Data Flow 和 Control Flow

一,Control Flow 在Control Flow中,Task是最小的单元,Task通过Precedence Constraint来保持同步. 1,Control Flow 不能在组件之间传递数据,用于串行或并行执行任务,担当Task的调度者. 如果两个Task之间没有设置precedence constraint,那么这两个Task是并发执行的.在design package时,最大限度地提高task的并发处理能力,能够充分利用server的资源,有助于减少ETL执行的时间. 2,Con