Linux基础知识

  • Linux基础知识已关闭评论
  • 278 人浏览
  • A+
所属分类:教程分享

本篇引见一些Linux信号处置惩罚相干内容.

1. 信号的观点

信号是历程间的一种异步通讯机制, 是软件层面临中断机制的模仿.

中断就是打断正在实行的顺序, 跳转到另一段顺序区实行, 实行终了后返回被打断的顺序继

续实行.

linux 体系中支撑的信号 1~64, unix 体系中支撑的信号 1~48

kill -l : 列出体系中支撑的一切信号

宏的称号以 SIG 开头, 运用宏能够防止差别体系对信号的编码差别

信号的实质就是一个数字, 编程时不发起直接运用该数字, 而是运用对应的宏, 如许可移植性高.

在 linux 体系中, 1~31 是不牢靠信号, 初期信号, 不支撑列队,34~64 是牢靠信号, 支撑列队, 不会丧失.

2. 信号的何发生

2.1 键盘发送, 只能发生部份信号

ctrl + c ---> 发送信号 SIGINT 2

ctrl + \ ---> 发送信号 SIGQUIT 3

2.2 顺序失足, 也是只能发生部份信号段毛病

段毛病 ---> SIGSEGV

总线毛病 ---> SIGIO

子历程完毕 ---> SIGCHLD

2.3 kill 敕令 ( 能够发一切的信号), 给指定的历程法 1~64 的信号

kill + 信号 + 历程PID ---> kill -9 1818

2.4 体系函数 kill 函数

int kill (pid_t pid, int sig);

3. 历程处置惩罚信号的体式格局

(1) 默许处置惩罚, 体系供应, 多半是退出历程, 会致使历程非正常退出

(2) 疏忽信号, 信号不被处置惩罚

(3) 自定义处置惩罚函数, 信号根据顺序员的代码举行处置惩罚

注重:

1) 有些信号是不能被自定义或许疏忽的, 比方信号 9 kill -9

2) 历程能够给其他的历程法信号, 然则只能给本用户的历程发信号, root 用户能够给一切 的用户历程发信号

4. 信号相干的 API

4.1 signal 函数

signal函数的作用有两个, 一是设置信号默许处置惩罚体式格局,二是注册一个信号处置惩罚函数

typedef void ( *sighandler_t ) ( int );sighandler_t signal ( int signum, sighandler_t handler ); signum: 信号对应的编号, 或许宏 handler: 能够有三个范例取值 (1) SIG_DFL 信号恢复成默许体式格局 (2) SIG_IGN 疏忽信号 ignore (3) 自定义函数的地点 函数指针  typedef void ( *sighandler_t ) ( int ); void (*)(int) 是函数指针范例, 指一个返回值为 void, 参数为 int 范例的函数指针范例

4.2 历程中信号的发送

kill(重点掌握) / alarm / raise / sigqueue

(1) kill() 函数

作用: 用于向任何历程组或历程发送信号

int kill (pid_t pid, int sig)pid : 指定被哪一个或许哪些历程发送信号 pid>0, 给 pid 对应的历程发送信号 pid=0, 本组一切历程发送信号 pid=-1, 给一切由权限的历程发送信号 pid<-1, 给某个历程组中的信号发送信息sig : 预备发送的信号代码,假如其值为零则没有任何信号送出,然则体系会实行毛病搜检,通常会应用sig值为零来磨练某个历程是不是仍在实行返回值 : 胜利实行时,返回0; 失利返回-1,毛病信息会存在于errno

注重: 不能给恣意的历程发信号, 比方给 1 号历程发送 SIGINT 信号是不可要的, 权限不够

(2) alarm() 函数

作用: seconds 秒后给当前历程发送一个 SIGALARM 信号

unsigned int alarm ( unsigned int seconds )seconds : 设置若干秒以后发送SIGALARM信号返回值 : 假如在seconds秒内再次挪用了alarm函数设置了新的闹钟,则背面定时器的设置将掩盖前面的设置,即之前设置的秒数被新的闹钟时候庖代;当参数seconds为0时,之前设置的定时器闹钟将被作废,并将剩下的时候返回

(3) raise()函数

作用: 用于向挪用历程发送信号

int raise ( int sig );sig : 预备发送的信号代码返回值 : 胜利实行时返回0,失利返回非0

总结:

int raise(int signum) 等价于 kill(getpid(),signum);

alarm(seconds) 等价于 sleep(seconds) + kill(getpid(),SIGALRM)

5. 信号的屏障

5.1 信号屏障信号的缘由

信号的发生有时候是没法肯定和掌握的, 能够运用信号屏障手艺让信号的处置惩罚时候延后, 信号屏障重要应用于症结代码的执阶段

信号屏障不是阻挠信号的到来, 信号是没法阻挠的, 而是将信号的处置惩罚延后, 待症结代码实行终了后再消除信号的屏障

5.2 信号屏障函数

sigprocmask() 函数能够完成信号的屏障和消除信号的屏障

int sigprocmask (int how, const sigset_t *set, sigset_t *oldset )how : 用于指定信号修正的体式格局,大概挑选有三种 SIG_BLOCK : 将set所指向的信号鸠合包括的信号加到当前的信号掩码中,即信号掩码和set信号集举行或操纵 SIG_UNBLOCK : 将set所指向的信号鸠合包括的信号从当前的信号掩码中删除,即信号掩码和set举行与操纵 SIG_SETMASK : 将set的值设定为新的历程信号掩码,即set对信号掩码举行了赋值操纵set : 为指向信号集的指针,在此专指新设的信号集,假如仅想读取如今的屏障值,可将其置为NULLoldset : 传出参数, 也是指向信号集的指针,在此寄存本来的信号集。可用来检测信号掩码中存在什么信号返回申明 : 胜利实行时,返回0。失利返回-1,errno被设为EINVAL

5.3 信号集操纵函数

(1) 将信号鸠合 set 中一切信号位置 1

int sigfillset(&set);

(2) 将信号鸠合 set 中一切信号为清 0

int sigemptyset(&set);

(3) 将信号鸠合 set 中与 signum 对应的 bit 置 1

int sigaddset(&set,signum);

(4) 将信号鸠合 set 中与 signum 对应的 bit 清 0

int sigdelset(&set,signum);

(5) 测试 signum 是不是为 set 中的一个成员

int sigismember(const &set,signum);

假如是个中一个成员返回 1, 不然返回 0

(6) 猎取被屏障的信号, 就是在实行症结代码时期发送过来的信号

int sigpending(&set);

引伸:

1. 主历程中挪用了 signal(SIGINT,...) ,然后实行 fork(), 那么子历程中在如何处置惩罚 SIGINT 信号

子历程继续了父历程的信号处置惩罚战略

2. 假如问题 1 中换成 vfork 会如何

vfork 建立子的子历程不会继续父历程的信号处置惩罚战略

腾讯云双十一活动