您的位置:首页 > 编程语言

《Unix高级环境编程》第八章 进程控制

2016-02-28 10:42 477 查看
Process Control

一、 介绍

本章着眼于Unix系统提供的进程控制。包含了新进程的创建、程序的执行、进程的中止。

此外也涉及到进程的各种ID-real(真实),effective(有效),and saved(保存的); user and group IDs—以及它们如何被进程控制原语(primitives)。

Interpreter files(解释器文件) and the
system
function。也会涉及到。

二、Process indentifiers

1-进程标识符是什么?

每个进程都有唯一的进程ID,是非负整数。

2-有什么用途

用于表示唯一进程

为其唯一性,应用程序经常用process IDs作为文件名的一部分,用于产生唯一的文件名。

3-Process 0是shceduler(调度器)被称为
swapper

disk上没有该程序,是内核的一部分,作为系统进程。

4-Process 1是
init
进程

是什么?

永远不会死亡的一般用户进程,而不是kernel里的系统进程。

作用:

是内核在
bootstrap
结束后调用。在新版本中程序文件存在
/sbin/init
中。该进程是负责加载
UNIX
系统,并使系统进入明确的状态,如multiuser。

5-Process 2是
pagedaemon

用于在
virtural memory system
中支持
paging


6-获取进程标识符(
identifies
)的系统调用

getpid等等,链接:/article/10324077.html

三、 fork Function

7-fork作用:

已经存在的进程通过
fork
创建新的进程。

链接如下:http://blog.csdn.net/feather_wch

8-父子进程的堆栈和数据空间

子进程复制了父进程的数据空间,栈,堆。

共享
text segment


9-
copy on write
(COW)是什么

自从
fork
经常接着调用
exec
,当前很多实现不执行完整的父数据,栈,堆的复制。这些区域是父子进程以
read-only
方式共享的。在需要修改这些区域的时候,kernel会以
page
进行复制。

10-Linux中
clone(2)
也能创建新进程

允许调用者控制父子进程共享什么内容

11-fork的特性,所有父进程打开的文件描述符都会复制到子进程中

因为对每个文件描述符都调用了
dup


父子进程给每个打开的描述符共享
file table entry


12-父子进程的文件结构,共享同样的file offset



父进程等待child完成再进行
write
操作,在child进行
write
后更新了
file offset
。然后父进程的操作会在该
offset
后进行
write


13- fork之后处理描述符的两种情况

父进程
wait
子进程的完成:父进程不需要做任何事情,子进程操作文件后会自动更新
file offset


父子进程各自做各自的事情:
fork
之后,父子进程关闭其不需要的描述符。

14-子进程继承父进程的属性

Real user ID, real group ID, effective user ID, and effective group ID

Supplementary group IDs

Process group ID

Session ID

Controlling terminal

The set-user-ID and set-group-ID flags

Current working directory

Root directory

File mode creation mask

Signal mask and dispositions

The close-on-exec flag for any open file descriptors

Environment

Attached shared memory segments

Memory mappings

Resource limits

15- 父子进程的不同之处

The return values from fork are different.

The process IDs are different.

The two processes have different parent process IDs: the parent process ID of the child is the parent; the parent process ID of the parent doesn’t change.

The child’s tms_utime, tms_stime, tms_cutime, and tms_cstime values are set to 0 (these times are discussed in Section 8.17).

File locks set by the parent are not inherited by the child.

Pending alarms are cleared for the child.

The set of pending signals for the child is set to the empty set.

16- fork的两种用法

当父进程想复制本身以至于父子能够执行代码的不同区域。如父进程接受
socket
传来的信息,子进程用于处理。

进程想执行不同的程序

四、vfork Function

调用方法和返回值与fork一样

链接:/article/10324079.html

17-vfork和fork
semantics
(语义)不同

fork
一样创建新的进程, 但child不引用的地址空间,不会复制到child中去

;child简单的在
vfork
之后调用
exec or exit
。换句话说,在执行
exec或者exit
之前,child运行在parent的地址空间。

vfork
保证
child
首先执行,直到
child
调用exec或者exit。调用之后,恢复parent的执行。

五、exit Function

18- 进程正常结束的五种方法

在main中return

执行exit

执行Exit和_exit

进程最后的线程的开始程序里执行return

最后的线程执行
pthread_exit


19- 进程异常终止的三种方法

接收到信号

调用
abort
,会产生
SIGABRT
信号

最后的线程响应取消的请求

20- 注意点

无论如何中止,kernel都会关闭该进程所有的描述符,并且释放空间。

三个exit函数,都会将exit状态作为函数的的参数

对于异常终止的情况,kernel会产生中止的状态(
termination status
),来表示异常终止的原因

exit status
最终会转换为
termination status


21- parent如何检查child的termination status?



22- 如果parent在child之前中止会发生什么?

init
进程会成为所有parent进程中止的child进程的父进程。

内核会在某进程中止的时候,查看该进程是不是现存的某些进程的父进程,如果是,则将相应进程的parent process ID 置为 1(
init
process ID = 1)

23- child在parent之前中止会发生什么?

kernel保存了所有中止进程的小部分信息(processID,中止状态,CPU执行时间),在parent调用
wait
or
waitpid
时可以获得这些信息。如果parent没有调用这些函数,已经中止的子进程处于
zombie
状态(使用ps可以查看有Z标志的进程)

24- 进程
init
进程的子进程中止后,会进入
zombie
状态吗?

不会!
init
会自动调用
wait
获取其中止状态

六、wait、waitpid、waitid Functions

当进程中止时,kernel会发送信号
SIGCHLD
给父进程。这是异步事件—可以在任何时候发送给parent,因此paren可以选择忽略或者提供
signal handler
进行处理。

链接:/article/10324082.html

25- wait和waitpid区别

wait
会阻塞直到子进程中止。
waitpid
能有
option
能防止阻塞

waitpid
不等待第一个中止的
child
process,有相应
option
控制等待哪个进程

status
如果不是
NULL
指针,返回的状态保存在里面

sys/wait.h 定义了如下macro(宏)查看中止状态



26- 参数pid的四种value

pid = -1, 等待任何子进程。在这种情况下
waitpid
等于
wait


pid > 0, 等待进程ID等于
pid
的子进程

pid == 0, 等待任何进程组ID等于调用进程的(process group id)的进程

pid < -1, 等待任何进程组ID(process group id)等于
pid
绝对值的子进程

27- wait的注意点

真正的错误是调用者用没子进程

其余的错误返回是因为
signal
中断

28- waitpid的注意点

返回值是中止的子进程的
进程ID


中止状态保存在
status
指向的参数里。

产生错误可能是因为指定的进程和进程组不存在,或者不是调用者的子进程

29- waitpid的options参数的作用



30- waitpid提供了三个wait不具备的特性

waitpid是我们等待一个特定的进程

waitpid提供了无阻塞版本的
wait


waitpid
使用
WUNTRACED
WCONTINUED
选项来支持
job control


27- waitid特点:

和waitpid一样允许等待指定的子进程

process ID
process group ID
使用了分离的参数,而不是像waitpid和wait一样合成为一个参数。

28- waitid参数说明

id参数的含义取决于idtype

idtype
如下



options决定调用者关心那些状态的改变



infop是结构体siginfo的指针

该结构体包含了在子进程中造成状态改变的信号的详细信息

八、wait3、wait4 Functions

链接:/article/10324083.html

29- wait3,wait4是什么?

提供了与
wait
waitpid
waitid
函数唯一不能提供的特性:增加了额外的参数,用于存放中止进程的所有资源的汇总和其所有的子进程

九、Race condition(竞争条件)

30- 进程等待父进程中止的方法

while(getppid() != 1)
sleep(1);


缺点:polling(轮询)会浪费很多CPU时间

避免竞争和轮询的方法

使用
signals


使用进程间通信IPC(interprocess communication)

十、exec Function

31- exec注意点:

调用
exec
的进程会完全被新的程序替代,从新程序的
main
开始执行

process ID保持保持原来的值,因为没有创建新的进程

exec
替换了当前进程的
text,data,heap,stack
segments

如果
execlp
execvp
通过路径找到的文件不是可执行文件,那么会认为该文件是
shell script
(脚本)文件,然后将其输入到
shell


l
代表是
list
,需要命令行参数是独立的参数,我们将该
argument
NULL
结尾。

v
代表是
vector


p
表示使用
filename
参数和
PATH
环境变量来查找文件

e
表示使用
environment list


32- fork和exec的区别

fork
创建新的进程

exec
初始化新的程序

33- process control primitives有哪些

fork,exec,exit,wait


34- close-on-exec

每个文件描述符都有
close-on-exec
flag,如果该
flag
被设置,文件描述符通过
exec
关闭,否则保持开启。

35- open directory streams调用
exec
后被关闭

因为
opendir
就调用了
fcntl
设置了
close-on-exec
flag

36- effective IDs

real IDs保持不变,effective IDs取决于被执行的程序文件的
set-user-ID
set-group-ID
位。如果被设置,effective IDs会变成该程序文件的
owner IDs


37- execve是唯一的系统调用

其余函数都是最终执行了该系统调用

十一、改变User IDs and Group IDs

改变ID可能会用到
setuid,setgid,setreuid,setregid,seteuid,setegid


链接:/article/10324086.html

十三、system Function

方便在程序中执行
command


链接:

38- system的具体实现内部有哪些系统调用?

fork
exec
waitpid


39- 使用
system
的优势!

相对于直接调用
fork和exec
system
能够处理
error
和处理
signal


40- 绝对不要在
set-user-ID
set-group-ID
程序里调用system,可以直接使用
fork和exec

这样做会产生安全漏洞

十四、Process Accounting

39 是什么?

开启之后,每次进程终止kernel都会将信息写入
accounting record
,比如:使用了多少CPU time,开始的时间等等。

40
acct
用于关闭 process accounting,
accton
用于开启

十五、User identification

41
getlogin
干什么?—用于得到登录名

#include <unistd.h>
char * getlogin(void);
// Returns: pointer to string giving login name if OK, NULL on error


十六、Process Time

42
times
作用

获取三种时间:
wall clock time
,
user CPU time
, and
system CPU time


//times - get process times
#include <sys/times.h>

clock_t times(struct tms *buf);
//Return: elapsed(溜走的) wall clock time in clock ticks if OK, -1 on error

struct tms {
clock_t tms_utime;  /* user time */
clock_t tms_stime;  /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};


43 如何使用

当前进程和子进程的 user/system CPU time 保存在参数的结构体中

wall clock time
是返回值。

我们一般使用相对时间,就是当前
times()
结果 - 以前
times()
结果,得到相对时间

44 返回值
clock_t
使用
sysconf(_SC_CLK_TCK)
(每秒钟ticks数目)来转换为秒数

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: