linux 信号编程

发送信号命令: 
kill  信号的发送命令  
kill -数字 +pid    —>给某个进程发送对应的信号值  
kill -l    			查看系统中的信号值
man 7 signal   	  —>查看信号的帮助文档

信号         值      动作   说明
──────────────────────────────────────────────────
SIGHUP        1       A     在控制终端上是挂起信号, 或者控制进程结束
SIGINT        2       A     从键盘输入的中断
SIGQUIT       3       C     从键盘输入的退出
SIGILL        4       C     无效硬件指令
SIGABRT       6       C     非正常终止, 可能来自 abort(3)
SIGFPE        8       C     浮点运算例外
SIGKILL       9      AEF    杀死进程信号
SIGSEGV      11       C     无效的内存引用
SIGPIPE      13       A     管道中止: 写入无人读取的管道
SIGALRM      14       A     来自 alarm(2) 的超时信号
SIGTERM      15       A     终止信号
SIGUSR1   30,10,16    A     用户定义的信号 1
SIGUSR2   31,12,17    A     用户定义的信号 2
SIGCHLD   20,17,18    B     子进程结束或停止
SIGCONT   19,18,25          继续停止的进程
SIGSTOP   17,19,23   DEF    停止进程
SIGTSTP   18,20,24    D     终端上发出的停止信号
SIGTTIN   21,21,26    D     后台进程试图从控制终端(tty)输入
SIGTTOU   22,22,27    D     后台进程试图在控制终端(tty)输出
以上的信号是常用信号
---------------------------------------------------------
SIGBUS      10,7,10     C     总线错误 (不正确的内存访问)
SIGPOLL                 A     I/O就绪事件 (Sys V). 等同于SIGIO
SIGPROF     27,27,29    A     系统资源定时器(Profiling timer)超时
SIGSYS      12,-,12     C     用错误参数调用系统例程 (SVID)
SIGTRAP        5        C     跟踪/断点自陷
SIGURG      16,23,21    B     套接口上出现 urgent 情况 (4.2 BSD)
SIGVTALRM   26,26,28    A     虚拟超时时钟 (4.2 BSD)
SIGXCPU     24,24,30    C     超过了CPU时间限制 (4.2 BSD)
SIGXFSZ     25,25,31    C     超过了文件大小限制 (4.2 BSD)
-----------------------------------------------------------
SIGIOT         6        C     IOT 自陷. 等同于 SIGABRT
SIGEMT       7,-,7
SIGSTKFLT    -,16,-     A     协处理器堆栈错误

SIGIO       23,29,22    A     I/O 有效信号 (4.2 BSD)
SIGCLD       -,-,18           等同于 SIGCHLD
SIGPWR      29,30,19    A     电源无效 (System V)
SIGINFO      29,-,-           等同于 SIGPWR
SIGLOST      -,-,-      A     文件锁丢失
SIGWINCH    28,28,20    B     窗口大小调整信号 (4.3 BSD, Sun)
SIGUNUSED    -,31,-     A     未使用的信号 (将成为 SIGSYS)
------------------------------------------------------------------
A      缺省动作是结束进程.
B      缺省动作是忽略这个信号.
C      缺省动作是结束进程, 并且核心转储.
D      缺省动作是停止进程.
E      信号不能被捕获.
F      信号不能被忽略.
------------------------------------------------------------------

如何捕抓linux系统中的信号: 
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数一:需要捕抓信号值  
参数二:对应的处理函数  
	   SIG_IGN  ->忽略该信号 
	   SIG_DFL  ->执行默认动作
       用户自定义动作void (*sighandler_t)(int)  -> 函数指针,指向返回类型为 void 参数为int的函数 (处理函数)

//信号的发送 
NAME
kill - send signal to a process
发送一个信号给进程
SYNOPSIS
#include <sys/types.h>
#include <signal.h>
 int kill(pid_t pid, int sig);
参数一:需要发送的进程pid  
参数二:需要发送的信号值
返回值:成功 0
      失败 -1
      
//假设不想通过pid来发送信号,想通过进程名字来发送
system("killall  -? 进程名");
system("killall -STOP mplayer")
system("killall -CONT mplayer")
 
给自己发送信号
#include <signal.h>
int raise(int sig); 等价于kill(getpid(), sig);

发送闹铃信号 
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
//参数一: seconds 在多少秒后触发一个闹钟信号
触发:   SIGALRM      14 信号
			
//获取系统时间
#include <time.h>
time_t time(time_t *tloc);
//把获取后的时间转换成字符串格式 
char *ctime(const time_t *timep);
//信号的屏蔽  :当解除屏蔽后,我们的信号还会再次触发。
当我们执行一些重要的初始化任务时,我们希望不被外界信号所干扰,所有我们需要把这些外来的信号给全部屏蔽掉。

信号屏蔽函数: 
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数一:SIG_BLOCK  阻塞 (在原来的基础上再添加) 
				  SIG_SETMASK 阻塞  (直接替换)
				  SIG_UNBLOCK 解除阻塞
参数二:信号操作集  新的
参数三:信号操作集  老的
返回值:成功: 0
	  失败: -1 

信号操作集的添加与解除请看图…
在这里插入图片描述在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
//信号处理函数
void func(int arg)
{
	printf("arg=%d\n",arg); //arg 当前触发的信号值
	printf("你杀不死我!\n");	
}

int main()
{
	//忽略ctrl c  
	signal(SIGINT,func);
	
	int i=0;
	while(1)
	{
		printf("i=%d\n",i++);
		if(i%3 == 0)
		{			
			//发送一个信号出去 
			kill(getpid(),SIGINT);
		}
		else if(i>10)
			break;
		sleep(1);
	}
	
	return 0;
}

运行效果如下图:
在这里插入图片描述

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

//信号处理函数
void func(int arg)
{
   printf("闹钟触发:%d\n",arg);
    time_t timep;
	//获取时间
	time(&timep);
	//转换时间
	printf("%s",ctime(&timep));

   alarm(1);//重新装置
}

int main()
{
	//注册闹钟信号
	signal(SIGALRM,func);
	
	int i=0;
	
	alarm(1);  //1S发送一个闹钟信号		
	while(1);
	return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
//信号处理函数
void func(int arg)
{
	printf("arg=%d\n",arg); //arg 当前触发的信号值
	printf("你杀不死我!\n");	
}

int main()
{
	//注册信号处理函数  
	signal(SIGINT,func);
	
	//屏蔽所有信号 
	//清空
	sigset_t set;
	sigemptyset(&set); 
	
	//添加所有信号操作集合 
	sigfillset(&set);
	
	//开启信号的屏蔽
	sigprocmask(SIG_BLOCK,&set,NULL);
	
	//开始做重要的任务
	int i=0;
	while(1)
	{
		printf("i=%d\n",i++);
		//解除屏蔽
		if(i==10)
		{
			sigprocmask(SIG_UNBLOCK,&set,NULL);
			break;
		}
		sleep(1);
	}
	
	printf("所有设备初始化完毕\n");
	while(1);
}

运行效果如图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值