Exceptional Control Flow(4)

Process Control 

Obtaining Process IDs 

Each process has a unique positive (nonzero) process ID (PID).

The getpid function returns the PID of the calling process.

The getppid function returns the PID of its parent (i.e., the process that created the calling process). 

Creating and Terminating Processes 

From a programmer’s perspective, we can think of a process as being in one of three states: 

(1) Running. The process is either executing on the CPU or is waiting to be executed and will eventually be scheduled by the kernel. 

(2) Stopped. The execution of the process is suspended and will not be scheduled.

A process stops as a result of receiving a SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU signal, and it remains stopped until it receives a SIGCONT signal, at which point it can begin running again.

(A signal is a form of software interrupt that is described in detail in Section 8.5.) 

 (3)Terminated. The process is stopped permanently. A process becomes termi- nated for one of three reasons: (1) receiving a signal whose default action is to terminate the process, (2) returning from the main routine, or (3) calling the exit function: 

The exit function terminates the process with an exit status of status. (The other way to set the exit status is to return an integer value from the main routine.) 

A parent process creates a new running child process by calling the fork function. 

The newly created child process is almost, but not quite, identical to the par- ent.

The child gets an identical (but separate) copy of the parent’s user-level virtual address space, including the text, data, and bss segments, heap, and user stack.

The child also gets identical copies of any of the parent’s open file descriptors, which means the child can read and write any files that were open in the parent when it called fork. The most significant difference between the parent and the newly created child is that they have different PIDs

The fork function is interesting (and often confusing) because it is called once but it returns twice:

once in the calling process (the parent), and once in the newly created child process.

In the parent, fork returns the PID of the child. In the child, fork returns a value of 0.

Since the PID of the child is always nonzero, the return value provides an unambiguous way to tell whether the program is executing in the parent or the child. 

Shared files. When we run the example program, we notice that both parent and child print their output on the screen.

The reason is that the child inherits all of the parent’s open files.

When the parent calls fork, the stdout file is open and directed to the screen.

The child inherits this file and thus its output is also directed to the screen. 

Reaping Child Processes 

When a process terminates for any reason, the kernel does not remove it from the system immediately.

Instead, the process is kept around in a terminated state until it is reaped by its parent.

When the parent reaps the terminated child, the kernel passes the child’s exit status to the parent, and then discards the terminated process, at which point it ceases to exist.

A terminated process that has not yet been reaped is called a zombie

If the parent process terminates without reaping its zombie children, the kernel arranges for the init process to reap them.

The init process has a PID of 1 and is created by the kernel during system initialization.

Long-running programs such as shells or servers should always reap their zombie children.

Even though zombies are not running, they still consume system memory resources

A process waits for its children to terminate or stop by calling the waitpid function. 

The waitpid function is complicated. By default (when options = 0), waitpid suspends execution of the calling process until a child process in its wait set terminates.  

If a process in the wait set has already terminated at the time of the call, then waitpid returns immediately

In either case, waitpid returns the PID of the terminated child that caused waitpid to return, and the terminated child is removed from the system. 

Determining the Members of the Wait Set 

The members of the wait set are determined by the pid argument: 

  • .  If pid > 0, then the wait set is the singleton child process whose process ID is equal to pid.

  • .  If pid = -1, then the wait set consists of all of the parent’s child processes. 

Modifying the Default Behavior 

The default behavior can be modified by setting options to various combinations of the WNOHANG and WUNTRACED constants:

(1) WNOHANG: Return immediately (with a return value of 0) if none of the child processes in the wait set has terminated yet.

The default behavior sus- pends the calling process until a child terminates.

This option is useful in those cases where you want to continue doing useful work while waiting for a child to terminate. 

(2) WUNTRACED: Suspend execution of the calling process until a process in the wait set becomes either terminated or stopped.

Return the PID of the terminated or stopped child that caused the return.

The default behavior returns only for terminated children.

This option is useful when you want to check for both terminated and stopped children. 

(3) WNOHANG|WUNTRACED: Return immediately, with a return value of 0, if none of the children in the wait set has stopped or terminated,

or with a return value equal to the PID of one of the stopped or terminated children. 

Checking the Exit Status of a Reaped Child 

If the status argument is non-NULL, then waitpid encodes status information about the child that caused the return in the status argument.  

The wait.h include file defines several macros for interpreting the status argument: 

(1) WIFEXITED(status): Returns true if the child terminated normally, via a call to exit or a return. 

(2) WEXITSTATUS(status): Returns the exit status of a normally terminated child. This status is only defined if WIFEXITED returned true

(3) WIFSIGNALED(status): Returns true if the child process terminated be- cause of a signal that was not caught.

(4) WTERMSIG(status): Returns the number of the signal that caused the child process to terminate.

This status is only defined if WIFSIGNALED(status) returned true

(5) WIFSTOPPED(status): Returns true if the child that caused the return is currently stopped

(6) WSTOPSIG(status): Returns the number of the signal that caused the child to stop. This status is only defined if WIFSTOPPED(status) returned true

Error Conditions 

If the calling process has no children, then waitpid returns −1 and sets errno to ECHILD.

If the waitpid function was interrupted by a signal, then it returns −1 and sets errno to EINTR. 

an example for waitpid function:

and notice that when all of the children have been reaped, the next call to waitpid returns −1 and sets errno to ECHILD.

example for waiting for pid in a certain order:

 

转载于:https://www.cnblogs.com/geeklove01/p/9250703.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值