进程控制

fork

创建子进程,也可理解为创建当前进程的拷贝(copy on write),新进程被视为原进程的子进程。
调用fork后,父子进程都会继续原来的执行流。
调用fork后,父进程返回的是子进程ID,子进程返回的是0。

同步问题
对于fork以后,父子进程共用相同的文件,子进程使用的是父进程文件的duplicated one。但他们都是共用同一个 file table 和 v-node table 的。这样就会产生同步问题。

继承
一下数据会从父进程继承到子进程中:
* ruid, rgid, euid, egid
* 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

以下数据在父子进程中会不同:
* The return values from fork.
* The process IDs and the parent process IDs.
* The child’s tms_utime, tms_stime, tms_cutime, and tms_cstime values are set to 0.
* 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.


有些系统结合fork和exec为一条命令:spawn 。

vfork

与fork类似,但子程序直接运行在父进程的上下文中(整个进程映像空间)。
该接口现已被废弃,不应再使用。

exit

内核始终会清除进程所分配的所有系统相关的资源。

exit status: 由三个exit函数的参数指定,或main函数中return的数值。
termination status: 系统识别的状态码。

exit status会在内核调用_exit的时候转换为termination status。

orphaned process
如果父进程在子进程终止之前就终止了,这些子进程的父进程会被设定为init进程。

zombie process
系统在进程终止后,会维护已终止进程的一些信息,以供其他进程(尤其是父进程)去获取这些已退出的进程的信息。
如果这些已终止的进程对应的父进程没有调用 wait 或 waitpid 去“等待”他们,则这些进程成为 zombie process 。

wait & waitpid

wait: 阻塞直到有一个子进程终止。
waitpid: 类似wait,但提供更多可配置项。

waitpid相较wait支持:
* 针对某一特定进程进行等待
* 可以配置为非阻塞
* 支持job control

可以使用以下宏来判断termination status(包含在sys/wait.h):
* WIFEXITED 正常退出
* WEXITSTATUS 获取exit status
* WIFSIGNALED 因接收信号而异退出
* WTERMSIG 获取信号
* WCOREDUMP 是否有CORE-DUMP文件生成
* WIFSTOPPED 子进程是否为STOPPED状态
* WSTOPSIG 致使子进程STOPPED的信号
* WIFCONTINUED 子进程是否在job control stop后继续。

waitid: 需要额外的参数,以提供比waitpid更灵活的功能。

wait3,wait4 BSD分支的拓展接口,相较前面的接口,此两个接口会返回所“等待”进程的资源使用描述。

这里写图片描述

race condition

fork是一个非常容易引发竞争条件的接口。因为fork以后,父子进程的执行流容易竞争访问相同的资源。

exec

这里写图片描述
这里写图片描述
exec 一共有7个不同的接口。

l = list, v = vector, e = environ, p = filename
其中,只有execve是系统接口,其他接口内部都会调用execve。

对于接收pathname参数的exec接口:
* 如果filename包含一个斜扛,则其会被视为pathname。
* 否则,所输入的可执行文件会在PATH环境变量的路径中搜索。
如果所指定的文件不是一个可执行文件,则会以shell script方式,通过/bin/sh打开:。

新程序会从进程中“继承”:
* Process ID and parent process ID
* Real user ID and real group ID
* Supplementary group IDs
* Process group ID
* Session ID
* Controlling terminal
* Time left until alarm clock
* Current working directory
* Root Directory
* File mode creation mask
* File locks
* Process signal mask
* Pending signals
* Resource limits
* Nice value(on XSI-conformant systems)
* Values for tms_utime, tms_stime, tms_cutime, and tms_cstime

euids会根据set-user-ID和set-group-ID的状态而决定是否改变。
如果set-user-ID置位,进程的euid会置为程序文件的拥有者ID。否则,euid不改变。group ID同理。

POSIX.1 规定, 所有打开的目录文件流都应该在exec时被关闭。

用户ID

更改用户ID的规则:
1. 如果进程具备超级用户权限,则setuid设置ruid, euid, saved set-user-ID 为 uid
2. 如果进程不具备超级用户权限,但 uid 等于 ruid 或 saved set-user-ID,则setuid只设置 euid 为 uid,ruid 和 saved set-user-ID 都不改变。
3. 如果前面两个条件都不成立,则error = EPERM,并返回错误。

内核维护用户ID的规则:
1. 只有超级用户进程才能更改 ruid 。
* 一般来说,ruid 是在用户登录的时候被超级用户进程 login(1) 设置的,且不会改变。
2. 在目标程序文件的 set-user-ID 标志位有效的情况下,euid 是在exec中被设置。如果 set-user-ID 标志无效,则exec 不改变当前的 euid。 euid 可以在任何时候通过调用 setuid 设置为 ruid 或 saved set-user-ID。
3. 在调用exec的时候,saved set-user-ID 会被设置为 euid 。如果文件的 set-user-ID 状态位置位,则这个操作(euid -> saved set-user-ID)会在exec把 euid 置为文件的用户ID之后执行。

Interpreter Files

#! pathname [ opt-args ]

pathname 通常是绝对地址,因为此处不会从PATH中搜索。

system

system内部会调用 fork, exec, waitpidi 。
system 的返回值由一下几种情况而定:
1. 若fork失败或waitpid返回错误,errno!=EINTR,则system返回-1, errno置为对应错误。
2. 若exec失败,则system返回同shell执行exit(127)的返回值。
3. fork, exec, waitpid都成功,则system返回shell的终止状态,可以从waitpid中获得。

process scheduling

nice value: 表示进程能分享多少CPU资源给其他进程,即对其他进程更nice。
取值范围: 0 ~ (2*NZERO)-1。NZERO是默认值。值越低表示越不nice,同时scheduling priority也会越高。

API

进程信息

getpid
getppid

进程用户信息

getuid
getgid
setuid
setgid
geteuid
getegid
seteuid
setguid
getresuid 获取 saved set-user-ID
getresgid 获取 saved set-group-ID
setreuid 同时设置 ruid 和 euid。BSD接口。
setregid 与上一个类似,但作用与group ID。
getpwuid 根据uid获取用户名,但UNIX可以为同一个用户ID指定多个名称。
getlogin 获取当前的login name。

process scheduling

nice
getpriority
setpriority

process time

times

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值