做空视频文件的网站,网站建设设计哪个济南兴田德润简介,wordpress 引用,海外人才招聘网《Linux操作系统原理分析之Linux 进程管理 5》#xff08;9#xff09; 4 Linux 进程管理4.5 Linux 信号4.5.1 信号的作用和种类1.信号机制2.信号种类 4.5.2 信号的处理4.5.3 信号处理函数1#xff0e;数据结构2#xff0e; 处理函数 signal3#xff0e;程序例 4 Linux 进… 《Linux操作系统原理分析之Linux 进程管理 5》9 4 Linux 进程管理4.5 Linux 信号4.5.1 信号的作用和种类1.信号机制2.信号种类 4.5.2 信号的处理4.5.3 信号处理函数1数据结构2 处理函数 signal3程序例 4 Linux 进程管理
4.5 Linux 信号
4.5.1 信号的作用和种类
1.信号机制
概念说明信号机制通信传输的本质传输称为信号的数值。信号主要作用把系统中发生的某些事件通知给进程。信号主要特征异步性即什么时候出现信号是不可预知的。信号数量它与硬件机器的字长相对应。如 80x86 的字长 32 位则信号有32 种。信号数量定义在哪里include/asm-i386/signal.h信号值系统中每个信号都是一个整数称为信号值。信号名为了清楚地表示信号的意义linux 通过宏定义给每个信号都定义了一个符号常量称为信号名。信号名格式。Linux 的信号名的组成以 SIG 打头后面跟着表示信号意义的英文缩写。
2.信号种类
信号值信号名信号意义缺省处理0用作特殊情况处理1SIGHUP进程的控制终端或控制进程已结束终止进程2SIGINT用户键入ctrl-c终止进程3SIGQUIT从键盘来的终止信号quit终止进程、core转储4SIGILL进程执行了非法指令或企图执行数据段终止进程、core转储5SIGTRAP跟踪中断、执行trap指令终止进程、core转储6SIGABRT进程发现错误并调试abort终止进程、core转储7SIGBUS进程访问非法地址、地址对齐出错终止进程、core转储8SIGFPE进程浮点运算错误、溢出、除数为0等终止进程、core转储9SIGKILL强制终止进程本信号不能屏蔽终止进程不能忽视10SIGUSR1保留给用户自行定义信号终止进程11SIGSEGV进程访问内存越界或无访问权限终止进程、core转储12SIGUSR2保留给用户自行定义信号终止进程13SIGPIPE进程向无读者的管道执行写操作终止进程14SIGALRM时钟定时信号由系统调用alarm发出终止进程15SIGTERM结束信号由kill命令产生终止进程16SIGSTKFLT进程发现堆栈溢出错误终止进程、core转储17SIGCHLD子进程结束或终止忽视18SIGCONT让暂停的进程继续执行终止进程19SIGSTOP暂停进程的执行不能屏蔽暂停进程不能忽视20SIGTSTP用户键入暂停通常是ctrl-z暂停进程21SIGTTIN后台作业要从用户终端stdin读数据暂停进程22SIGTTOU后台作业写用户终端stdout暂停进程23SIGURG套接字socket有“紧急”数据到达忽视24SIGXCPU进程使用CPU超时终止进程、core转储25SIGXFSZ进程处理文件超长终止进程、core转储26SIGVTALRM虚拟时钟信号计算进程占用CPU时间终止进程27SIGPROF类似SIGALRM/SIGVTALRM计算进程占用CPU时间以及系统调用的时间终止进程28SIGWINCH终端窗口大小已改变忽视29SIGIOI/O准备就绪可以进行输入/输出操作忽视30SIGPWR系统电源失效31SIGUNUSED未使用
信号产生的三种情况 1进程在执行过程中发生了某种错误标志被置位系统内核识别到错误标志向有关进程发送相应信号通知进程发生了运行错误。 2系统或用户发出的控制进程终止或暂停的信号。 3内核需要控制进程的运行而产生的信号。
4.5.2 信号的处理
1 在进程的任务结构体 task_struct 中有两个成员项用于处理接收的信号
Unsigned long signal
Unsigned long blocked它们都是位域Bitmap形式的 32 位 unsigned long 型变量每一位bit对应一种信号。变量的第 0位对应信号值为 1 的 SIGHUP第 1 位对应信号值为 2 的 SIGINT依此类推。 1Signal存放进程收到且尚未处理的信号。 进程可以同时接收多个信号 每种信号在 signal 中只有一位故不能识别接收了一个还是多个同一个信号 信号没有优先级可以以任意顺序处理接受到的信号 2 Blocked通过将 blocked 中的某一位设置为 1来屏蔽某种信号的处理。但是有两个不能屏蔽的信号SIGKILL 和 SIGSTOP是不能被屏蔽的blocked 中它们对应的位始终为 0
2进程接收到信号后的两种处理方式 交给内核进行处理缺省方式 由进程自行处理 1其中 core 转储指把该进程内存中的有关信息进行转储dump生成 core 文件。在使用 gdb 调试工具对程序进行调试时通常需要使用 core 文件。 2进程接收到信号后有其自行处理成为信号的捕获但是信号 SIGKILL 和 SIGSTOP 不能有进程捕获他们必须由内核进行处理。 3信号无论是由内核或是进程处理都可以 被忽视即不进行任何处理但是信号 SIGKILL 和SIGSTOP 不能被忽视。
4.5.3 信号处理函数
1数据结构
当进程接收到信号并且该信号没有被阻塞的话进程就执行信号处理函数完成对信号的处理每种信号都有其对应的处理函数进程对所有信号处理函数集中由 signal_struct 结构体来管理进程任务结构体中成员项 sig 指向该结构体。在 include/linux/sched.h 中定义了 signal_struct 结构体
Struct signal_struct{
Int count
Struct sigaction action[32]
};count共享处理信号函数的计数值。一般是子进程继承父进程的信号机制时的计数。 action[]是该进程的信号处理函数表32个元素对应 32 种信号。该数组是 sigaction 结构体它定义在/ include/asm-i386/signal.h 中 Struct sigaction {
_sighandler_t sa_handler
Sigset_t sa_mask;
Unsigned long sa_flags;
Void(*sa_restorer)(void);
};sa_handler 是指向信号处理函数的指针,通常是用户自行设定的信号处理函数。当 sa_handler 的值是系统定义的以下符号常量时它不是信号处理函数的入口地址其值和意义如下 SIG_DEL 0 缺省处理由内核执行系统设定的信号处理函数 SIG_IGN 1 忽视信号不进行信号处理 SIG_ERR -1 信号处理时返回的错误一般用于判断函数的返值是 否正确。 sa_mask 是一个信号屏蔽码当进程处理某一个信号时它被逻辑加OR到接收进程的信号 屏蔽码 blocked 上进程信号屏蔽码的这种改变只是在信号处理期间有效其目的是在进程执行 信号处理过程中屏蔽其它到达的信号。 sa_flags 是信号处理标志主要有 SA_ONESHOT 信号到达时启动信号处理函数 SA_NOMASK 不使用 sa_mask改变进程的信号屏蔽码 sa_restorer 是一个函数指针目前未用保留以供扩充。 2 处理函数 signal
Linux 系统提供了用户自己设置信号处理函数的方法它由系统调用 signal完成。在 signal中进一步调用内核函数 sys_signal实现函数设置的功能。该内核函数定义在 kernal/signal.c 中
Asmlinkage unsigned long sys_signalint signum_sighandler_t handler;参数说明 signum信号值指明要设置哪个信号的函数 handler用户设置的处理函数的首地址。也可以是 SIG_DEL、SIG_IGN 函数简要说明
Struct sigaction tmp/*用于暂存信号处理函数的有关信息。*/
…
Ifsignum1|| signum32 return –EINVAL; /*判断 signum 给定的信号值是否合理*/
IfsignumSIGKILL||signumSIGSTOPreturn –EINVAL; /*若为这两个信号则不能被捕获即用户不能为它们设定处理函数*/
IfhandlerSIG_DFL handlerSIG_IGN /*若信号不是指定为缺省处理或
{ 忽视则确认给定的处理函数使用存储空间的有效性*/
Err verify_area(VERIFY_READhandler1)
Iferrreturn err
}经过上面的检查确认后开始使用 tmp 设置进程的 sigaction 结构体。
Memsettmp,0,sizeof(tmp); /* 首先把该结构的存储空间全部清 0*/
Tmp.sa_handler handler/*把参数 handler 指定的信号函数处理函数首地址置入 tmp 的sa_handler*/
Tmp.sa_flags SA_ONESHOT|SA_NOMASK; /*设置 sa_flag*/
Current-sig-action[signum-1]tmp; /*把 tmp 的内容复制到当前进程的处理信号函数表中与指定信号对应的数组元素中。*/
Check_pending(signum); /*设置当前进程任务结构体的 signal 成员项*/
Returnunsigned longhandler /*返回 handler 的值即原信号处理函数的首地址*/3程序例
#include stdio.h
#include signal.h
#include unistd.h
Int count0;
Void ctrl_c_count(int);
Main()
{
int c;
void(*old_handler)(int);
old_handlersignal(SIGINT,ctrl_c_count);
while((cgetch()!”\n”);
printf(“Ctrl_C count%d\n”,count);
signal(SIGINT,old_handler);
}
Void ctrl_c_count(int dump)
{
Printf(“Ctrl_C\n”);
Count;
}