信号
(1)信号的概念
共性:1简单 2.不能携带大量信息3.满足某个特定条件发送
信号 信息的载体 linux经典的通信方式
软中断,硬件中断
软件:软中断
每个进程收到的所有信号,都是由内核负责发送,内核处理
由于时间特别短,可以忽略延迟
(2)产生信号的基本方法
1.通过按键产生 ctrl+c,ctrl+z
2.系统调用产生:kill, abort
3.软件条件产生:定时器 alarm
4.硬件异常产生:非法内存访问(段错误),除0,内存对齐出错总线程错误()
4.命令尝试:kill
(3)信号的处理方式
1.执行默认动作
1》Term 终止进程
2》 Ign 忽略信号
3》 Core 终止进程,并尝试core文件
4》 Stop 停止(暂停进程)
5》Cont 继续运行进程
2.忽略
3捕捉
9号19号信号不能被捕捉
一般信号的操作都使用宏定义来操作,不容易产生歧义
(4)信号捕捉:signal函数
1.捕捉型号干什么
typedef signal(捕捉的信号,来做什么)
(5)kill函数的使用
使用的头文件:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid , int sig)
参数一:pid 为要结束的进程ID号
- pid大于零时,pid是信号欲送往的进程的标识。
- pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。
- pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。
- pid小于-1时,信号将送往以-pid为组标识的进程。
参数二:sig:准备发送的信号代码,假如其值为零则没有任何信号送出,但是系统会执行错误检查,通常会利用sig值为零来检验某个进程是否仍在执行。
(6)alarm函数 设置定时器
#include <unistd.h>
unsigned int alarm ( unsigned int seconds)
SIGALRM :定时器 超时时间有系统调用alarm 设置
默认动作为终止进程
alarm函数是设置一个计时器, 在计时器超时的时候, 产生SIGALRM信号. alarm也称为闹钟函数,一个进程只能有一个闹钟时间。如果不忽略或捕捉此信号, 它的默认操作是终止调用该alarm函数的进程
每个进程有且只有一个定时器,它的主要功能是设置信号传送闹钟。其主要功能用来设置信号SIGALRM在经过seconds指定的秒数后传送给目前的进程
alarm(5)–3sec
返回值 :返回剩余的秒数
alarm(5)–3s–alarm(5)
剩余7s,有且只有一个闹钟
(7)信号集操作函数
进程中有PCB里面有两个信号集
一个未决信号集 ,发送未被处理
000100000
123456789
1是收到了但是没有做的事情
一个堵塞信号集会影响堵塞信号集
0000000
1234567
设定一个信号来影响堵塞信号集来定义一个集合
来影响信号集,来设置一个自己的信号集
信号集的操作函数
#include <signal.h>
sigset_t myset;定义一个集合:影响未觉信号集
//自定义集合
int sigemptyset(sigset_t set)//集合清0
int sigfillset(sigset_tset)信号集置1
int sigaddset(sigset_tset,int signo)//将某个信号加入信号集
int sigdelset(sigset_t* set ,int signo)删除出信号集
int sigismember(const sigset_tset,int signal)//判断某个函数是否在集合中
int sigprocmask(int how ,const sigset_tset ,sigset_t*oset)读取或更改屏蔽字符
第一参数屏蔽信号 与把屏蔽信号解除 第二参数自己的信号集 第三参数将系统替换的东西放到某一个集合中
前提条件是信号有参数
用来影响(屏蔽)或者解除信号,读取或修改进程的信号屏蔽字
sigpending(sigset_t *set)通过这个函数读取当前进程的未决信号集
拥有以下函数
(8)wait/waitpid 回收僵尸进程操作
#include 《sys/tupes.h》
pid_t wait (int *status);
int *status参数是为了传出一个状态值
三个作用:
1.阻塞等待子进程回收,父进程不干其他事情
2.调用wait,把子进程资源回收
3.pcb留着的作用,就是给父进程查询依据
缺点(父进程不干事)
pid_t waitpid(pid_t pid ,int *status,)
WIFEXITED(status)这个宏判断为帧,表示进程正常退出
WEXITSTATUS(status)上一个宏伟帧,则返回状态值
获取status
wait(&status)记得加取地址符
exit(num)里面的数字不能超过128
异常退出:内存出错,段错误,浮点出错。异常信号
WIFSIGNALED(status)异常退出 宏为真,表示异常终止
WTERMSIG(status)返回异常退出的状态值
pid_t waitpid(pid_t pid ,int *status, int options);
参数
第一个参数是进程的pid代号,第二个是返回值,,第三个是宏
waitpid(pid3,NULL,0)=wait(NULL)
waitpid(-1,NULL,0);所有都是阻塞回收
非阻塞回收 int wqid= waitpid(-1,NULL,WNOHANG)宏是轮训,一段时间来看一次子进程是否结束
返回值就是回收进程的pid采用非组设做法回收一个子进程
if(wqid>0)
{
n–;
}
(10)exec家族
fork完以后用 exec函数 把另一段代码替代子进程的代码
#include
execl("/bin/ls",“ls”,"-l",NULL);
execl(“代码的路径”,“”“”,哨兵)