linux内核——内核信号量

需要解决的问题:

1、系统中什么是信号、有什么信号?

2、系统接收到信号,如何处理?

3、信号的作用。

一、linux内核中的信号

#define SIGHUP		 1
#define SIGINT		 2
#define SIGQUIT		 3
#define SIGILL		 4
#define SIGTRAP		 5
#define SIGABRT		 6
#define SIGIOT		 6
#define SIGUNUSED	 7
#define SIGFPE		 8
#define SIGKILL		 9
#define SIGUSR1		10
#define SIGSEGV		11
#define SIGUSR2		12
#define SIGPIPE		13
#define SIGALRM		14
#define SIGTERM		15
#define SIGSTKFLT	16
#define SIGCHLD		17
#define SIGCONT		18
#define SIGSTOP		19
#define SIGTSTP		20
#define SIGTTIN		21
#define SIGTTOU		22

在这里插入图片描述

二、系统如何调用接受的信号与作用 

        do_signal函数是内核系统调用中断(int 0X80)中断处理子程序的预处理程序,该函数的主要作用是将信号的处理句柄插入到用户程序堆栈中,系统调用后就会执行

        sys_signal由函数库提供,用于恢复系统调用后的返回值和一些寄存器。编译链接时由libc函数库提供,用于 在信号处理程序结束后清理用户态堆栈,并恢复系统调用存放在eax中的返回值。

在这里插入图片描述

        信号作用:信号是进程间通信的简单的消息,信号虽然不带任何信息。但是子进程结束后他会产生一个17信号给父进程,显示子进程当前的状态。信号处理函数会被压入用户堆栈 。

三、信号处理的流程

在system_call.s中,可以看到首先调用的是do_signal进行预处理,再调用sys_signal信号处理 。

call sys_call_table(,%eax,4)        # 间接调用指定功能C函数
	pushl %eax                          # 把系统调用返回值入栈




incl %ecx                       # 将信号调整为从1开始的数(1-32)
	pushl %ecx                      # 信号值入栈作为调用do_signal的参数之一
	call do_signal                  # 调用C函数信号处理程序(kernel/signal.c)
	popl %eax                       # 弹出入栈的信号值
3:	popl %eax                       # eax中含有上面入栈系统调用的返回值
	popl %ebx
	popl %ecx
	popl %edx
	pop %fs
	pop %es
	pop %ds
	iret

        3.1 do_signal

        由于C函数是传值函数,因此给eip赋值时需要使用'*(&eip)'的形式。

         3.2 sys_signal

        signal()系统调用。类似于sigaction()。为指定的信号安装新的信号句柄(信号处理程序)。 信号句柄可以是用户指定的函数,也可以是SIG_DFL(默认句柄)或SIG_IGN(忽略)。参数signum --指定的信号;handler --指定的句柄;restorer --恢复函数指针,该函数由Libc库提供。用于在信号处理程序结束后恢复系统调用返回时几个寄存器的原有值以及系统 调用的返回值,就好像系统调用没有执行过信号处理程序而直接返回到用户程序一样。 函数返回原信号句柄。

int sys_signal(int signum, long handler, long restorer)
{
	设置分配一个信号结构体
	struct sigaction tmp;
	检索信号范围要在1-32并且不是终止信号			
	if (signum<1 || signum>32 || signum==SIGKILL)
		return -1;
	指定信号处理句柄
	tmp.sa_handler = (void (*)(int)) handler;
	设置屏蔽码
	tmp.sa_mask = 0;
	设置改信号的状态为只可执行一次就恢复到默认值 
	tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
	保存回复处理程序指针
	tmp.sa_restorer = (void (*)(void)) restorer;
	更新当先标识指针的信号信息
	handler = (long) current->sigaction[signum-1].sa_handler;
current->sigaction[signum-1] = tmp;
	return handler;
}

注意:

        当一个子进程终止或结束时都给父进程发送一个标号为17的SIGCHLD信号,用来通知父进程子进程的当前状态。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西邮小菜机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值