导航
当前章节:进程
原文链接:进程
上一章节:文件IO
下一章节:管道
目录:Linux程序设计
进程
介绍
进程是程序的一个正在运行的实例。用pid唯一标识
fork创建子进程,folk返回0为子进程,>0为父进程,值为子进程pid
进程创建流程:fork创建一个子进程,子进程exec运行新文件,父进程wait等待子进程结束回收进程。
僵尸进程:当一个子进程终止时,它将变成僵尸,直到父进程调用wait()。僵尸消耗系统资源。
ps -t tty1
ps -A -ostat,ppid,pid,cmd | grep -E ‘[Zz|
- Z 状态:这表示进程是僵尸进程。
- 失效状态:在 BSD 系统上,僵尸进程被标记为
- 非零 pid 但命令名称为空:进程已终止,但 pid 尚未重新分配。
孤立进程:父进程已终止的子进程。孤儿被init收养。
守护进程:与终端无关的后台进程。
fork()
#include <unistd.h>
pid_t p1= fork(void);
wait():等待子进程,返回回收的子进程pid
wait();
pid_t waitpid(pid_t pid,int *status,int options);
waitpid(int i):等待子进程,返回回收的子进程pid,如果没有子进程返回0
i<-1和i>0:等待pid=|i|进程, i==-1 等待任意子进程,i=0:等待同一进程组的进程
exec
exec是常用的系统调用函数族,用于将当前进程替换为新的程序。
它通常和 fork() 函数一起使用,先通过 fork() 创建子进程,
然后在子进程中调用 exec 函数来加载并执行一个新的程序
主要包括以下6各函数:
- execl(路径,arg0,arg1,…,argn,NULL);
- execle(路径,arg0,arg1,…,argn,NULL,envp);
- execlp(文件,arg0,arg1,…,argn,NULL);
- execv(路径,argv);
- execve(路径、argv、envp);
- execvp(文件,argv);
execl与execv差别:execl参数单个结尾为NULL,而execv传入一个参数数组
execle与execl差距:增加envp为环境参数,其它的为默认当前环境
有p的函数会在系统环境中寻找对应的可执行文件,没有p需要指明完整路径
信号处理
程序有时候需要对一些信号进行处理,如指定Ctrl+C时的程序行为,可以使用signal或sigaction函数实现。
signal(SIGINT, sigint_handler):信号处理函数,当收到结束信号时执行handler函数
- SIGINT - Interrupt signal (sent by Ctrl+C)
- SIGKILL - Kill signal
- SIGTERM - Termination signal
- SIGSTOP - Stops (pauses) the process
- SIGCONT - Continues (unpauses) a stopped process
SIG_DFL为默认信号处理函数
kill -s指定信号的命令
sigprocmask() 阻断信号
sigaction
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
signum - 要修改的信号编号,如 SIGINT。
act - 指向 sigaction 结构的指针,定义信号传递时要采取的新操作。
oldact - 指向 sigaction 结构的指针,其中将存储先前的信号操作。 可以为 NULL。
struct sigaction {
void (sa_handler)(int); / SIGINT handler */
void (*sa_sigaction)(int, siginfo_t *, void );
sigset_t sa_mask; / Signals to block /
int sa_flags; / Flags */
void (*sa_restorer)(void);
};
signal和sigaction
signal使用了简单的信号处理模型,即信号发生时,进程会调用相应信号处理函数执行特定的操作,简单易用,但是具有一些局限性。
而sigaction使用更加灵活地设置信号的处理方式