linux中的信号

1.什么是信号
1.1 信号是内容受限的一种异步通信机制
(1)信号的目的:用来通信
(2)信号是异步的(对比硬件中断)
(3)信号本质上是int型数字编号(事先定义好的)
1.2 信号由谁发出
(1)用户在终端按下按键
(2)硬件异常后由操作系统内核发出信号
(3)用户使用kill命令向其他进程发出信号
(4)某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向一个读端已经关闭的管道write时会产生SIGPIPE信号
1.3 信号由谁处理、如何处理
(1)忽略信号
(2)捕获信号(信号绑定了一个函数)
(3)默认处理(当前进程没有明显的管这个信号,默认:忽略或终止进程)

2.常见信号介绍
(1)SIGINT                      2        Ctrl+C时OS送给前台进程组中每个进程
(2)SIGABRT                  6        调用abort函数,进程异常终止
(3)SIGPOLL    SIGIO    8        指示一个异步IO事件,在高级IO中提及
(4)SIGKILL                    9        杀死进程的终极办法
(5)SIGSEGV                11        无效存储访问时OS发出该信号
(6)SIGPIPE                  13        涉及管道和socket
(7)SIGALARM              14        涉及alarm函数的实现
(8)SIGTERM                15        kill命令发送的OS默认终止信号
(9)SIGCHLD                17        子进程终止或停止时OS向其父进程发此信号
(10)
SIGUSR1                     10        用户自定义信号,作用和意义由应用自己定义
SIGUSR2                     12

3.进程对信号的处理
3.1 signal函数介绍
3.2 用signal函数处理SIGINT信号
(1)默认处理
(2)忽略处理
(3)捕获处理
细节:
(1)signal函数绑定一个捕获函数后信号发生后会自动执行绑定的捕获函数,并且把信号编号作为传参传给捕获函数
(2)signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数
3.3 signal函数的优点和缺点
(1)优点:简单好用,捕获信号常用
(2)缺点:无法简单直接得知之前设置的对信号的处理方法
3.4 sigaction函数介绍
(1)2个都是API,但是sigaction比signal更具有可移植性
(2)用法关键是2个sigaction指针

sigaction比signal好的一点:sigaction可以一次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数不能单独获取旧的捕获函数而必须在设置新的捕获函数的同时才获取旧的捕获函数

信号与槽

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

typedef void (*sighandler_t)(int);


void func(int sig)
{
	if (SIGINT != sig)
		return;
	
	printf("func for signal: %d.\n", sig);
}


int main(void)
{
	sighandler_t ret = (sighandler_t)-2;
	signal(SIGINT, func);
	//signal(SIGINT, SIG_DFL);		// 指定信号SIGINT为默认处理
	//ret = signal(SIGINT, SIG_IGN);		// 指定信号SIGINT为忽略处理 Ctrl+C信号
	if (SIG_ERR == ret)
	{
		perror("signal:");
		exit(-1);
	}
	
	printf("before while(1)\n");
	while(1);
	printf("after while(1)\n");
	
	return 0;
}

4.alarm和pause函数
4.1 alarm函数
(1)内核以API形式提供的闹钟
(2)编程实践

4.2 pause函数
(1)内核挂起
(2)代码实践
pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,要退出pause状态当前进程需要被信号唤醒
4.3 使用alarm和pause来模拟sleep

#include <stdio.h>
#include <unistd.h>			// unix standand
#include <signal.h>

void func(int sig)
{
	/*
	if (sig == SIGALRM)
	{
		printf("alarm happened.\n");
	}
	*/
}

void mysleep(unsigned int seconds);

int main(void)
{
	printf("before mysleep.\n");
	mysleep(3);
	printf("after mysleep.\n");
	
/*	unsigned int ret = -1;
	struct sigaction act = {0};
	
	act.sa_handler = func;
	sigaction(SIGALRM, &act, NULL);
	
	//signal(SIGALRM, func);
	ret = alarm(5);
	printf("1st, ret = %d.\n", ret);

	sleep(3);
	
	ret = alarm(5);		// 返回值是2但是本次alarm会重新定5s
	printf("2st, ret = %d.\n", ret);
	sleep(1);
	
	ret = alarm(5);
	printf("3st, ret = %d.\n", ret);
	
	//while (1);
	pause();		
*/	
	return 0;
}

void mysleep(unsigned int seconds)
{
	struct sigaction act = {0};
	
	act.sa_handler = func;
	sigaction(SIGALRM, &act, NULL);
	
	alarm(seconds);
	pause();
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值