一.进程(续)
1.vfork创建子进程
其与fork函数的区别为vfork创建的子进程,会保证子进程先运行,只有当子进程退出(或调用exit函数)时,父进程才运行
只要原因是vfork创建的子进程和父进程共用一个空间
pid_t vfork();
2.exec函数族
是在进程中启动另一个进程(即程序中启动另一个程序)
列举部分函数:
#include <unistd.h>
//path为执行文件的路径,arg为文件名,...为执行程序的参数其需要以NULL结尾
int execl(const char *path,const char *arg,...);
int execv(const char *path,char *const arg[]);
函数中 l(list) 为列表方式传参,v(vector)为使用指针数组传参
注意:exec函数执行前的代码能执行,但在函数执行成功后的其之后的代码无法执行;原因为在执行函数后其会开辟新的空间,而新空间中没有其之后的代码
二.信号
1.信号概述
信号是一种异步通信的方式,其是软件中断,可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件
信号的特点:简单,不能携带大量信息,满足某个特设条件才发送
信号的周期:
- 信号的产生
- 信号在进程中的注册
- 信号在进程中的注销
信号的四要素(可以使用 man 7 signal 查看):
- 编号
- 名称
- 事件
- 默认处理动作
发起信号的方式:
- 当用户按某些终端键时,将产生信号
- 硬件异常将产生信号,如除数为0,无效的内存访问等
- 软件异常将产生信号(定时器)
- 调用系统函数(如:kill、raise、abort)将发送信号
- 运行kill / killall命令将发送信号
未决信号集:信号发生但未被处理的信号集合
信号阻塞集:加入信号阻塞集的信号不被处理
2.信号的API
kill函数:
#include <sys/types.h>
#include <signal.h>
//给指定进程发送指定信号(不一定杀死)
int kill(pid_t pid,int sig);
pid的取值:
- pid>0:将信号传送给进程ID为pid的进程
- pid=0:将信号传送给当前进程所在进程组中的所有进程
- pid=-1:将信号传送给系统内所有的进程
- pid<-1:将信号传给指定进程组的所有进程
sig:为信号的编号,可以填数字编号
raise函数:
#include <signal.h>
//给当前进程发送指定信号
int raise(int sig);
abort函数:
#include <stdlib.h>
//给自己方式异常终止信号6(SIGABRT),并产生core文件
void abort();
alarm函数:
#include <unistd.h>
//设置定时器,在指定几秒后,内核会给当前进程发14(SIGALRM),进程收到后,默认终止动作
unsigned int alarm(unsigned int seconds);
当需要取消定时器时,将参数改为0,并返回剩余时间数
3.注册信号自定义函数
SIGKILL(9)和SIGSTOP(19)不能更改信号的处理方式,因为其为用户提供了一种使进程终止的可靠方法
自定义信号的函数有signal和sigaction
#include <signal.h>
//函数的定义规范,无返回值,参数为int类型
typedef void(*sighandler_t)(int);
//确定收到信号后处理函数的入口地址
sighandler_t signal(int signum,sighandler_t handler);
signum:为信号的编号,可以是数字编号,也可以使宏定义
handler的3种取值情况:
- SIG_IGN:忽略该信号
- SIG_DFL:执行系统默认动作
- 信号处理函数名:自定义的信号处理函数
#include <signal.h>
//检查或修改指定信号的设置
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
signum:要操作的信号
act:对信号的新处理方式,当其非空则改变指定信号的处理方式
oldact:原来对信号的处理方式,则系统将此前指定信号的处理方式存入oldact
其结构体:
struct sigaction{
void(*sa_handler)(int); //旧的信号处理函数指针
void(*sa_sigaction)(int,siginfo_t *,void *); //新的信号处理函数指针
sigset_t sa_mask; //信号阻塞集
int sa_flags; //信号处理的方式,通常为0
}
新的处理函数参数:
第一个为信号的编号
第二个为记录信号发送进程信息的结构体
第三个为可以赋给指向类型的一个对象的指针,以引用在传递信号时被中断的结束进程或线程的上下文