1.概念
进程:一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源。
每个进程都会被分配一个唯一的数字编号,称为进程标识符或PID ,PPID 是其父进程的PID。
PID为1的时特殊进程 init,是系统运行的第一个进程,是其他进程的祖先进程,管理其他进程。
进程采用抢占式多任务处理,根据优先级分配时间片,可以用nice和renice调整优先级(默认为0)
进程的状态STAT(可以用 ps ax 命令查看)
STAT代码 | 说明 |
S | 睡眠 |
R | 可运行 |
D | 不可中断的睡眠(等待) |
T | 停止 |
Z | 死进程或僵尸进程 |
N | 低优先级任务 |
W | 分页 |
s | 进程是会话期首进程 |
+ | 进程属于前台进程组 |
l | 进程是多线程的 |
< | 高优先级任务 |
2.启动新进程
#include<stdlib.h>
int system(const char *string);
相当于shell中 执行:$ sh -c string (system依赖于shell,而且效率不高,不建议)
较有效的函数是 exec,用于替换进程映像,当然最常用的还是fork(复制进程映像):
#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);
fork创建一个新进程,父进程中 fork 调用返回新的子进程PID,子进程中的 fork 调用返回0。如果 fork 失败返回-1。
3.等待进程
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *stat_loc);
wait系统调用将暂停父进程直到它的子进程结束为止,返回子进程的PID 。
如果 stat_loc 不是空指针,状态信息将被写入它所指向的位置,可以用sys/wait.h 中定义的宏解释状态信息:
宏 | 说明 |
WIFEXITED(stat_val) | 如果子进程正常结束,它就取一个非零值 |
WEXITSTATUS(stat_val) | 如果 WIFEXITED非零,它返回子进程的退出码 |
WIFSIGNALED(stat_val) | 如果子进程因为一个未捕获的信号而终止,它就取一个非零值 |
WIERMSIG(stat_val) | 如果WIFSIGNALED非零,它返回一个信号代码 |
WIFSTOPPED(stat_val) | 如果子进程意外终止,它就取一个非零值 |
WSTOPSIG(stat_val) | 如果WIFSTOPPED非零,它返回一个信号代码 |
4.僵尸进程
一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。
#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid, int *stat_loc, int options);
options参数用来改变waitpid的行为,最有用的一个选项是 WNOHANG,作用是防止waitpid调用将调用者的执行挂起。
如果想让父进程周期性地检查某个特定的子进程是否已终止,可用下面方式:
waitpid(child_pid, (int *) 0, WNOHANG);
如果子进程没有结束或意外终止,返回0,否则返回child_pid。如果waitpid失败,返回-1