linux 信号

原创:http://blog.sina.com.cn/u/2312748742

一、1、信号是一种软中断,2、信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据,3、收到信号的进程对各种信号有不同的处理方法。4、进程通过系统调用signal来指定进程对某个信号的处理行为。

二、信号 值 处理动作 发出信号的原因 :
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下)
SIGQUIT 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令
SIGFPE 8 C 浮点异常
SIGKILL 9 AEF Kill信号
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 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写

三、信号的安装处理:

void (*signal(int signum, void (*handler))(int)))(int);

该函数有两个参数, signum指定要安装的信号, handler指定信号的处理函数.

该函数的返回值是一个函数指针, 指向上次安装的handler

四、例子:

#include<stdio.h>
#include<signal.h>
int counts=0;
void signal_callback(int nums)
{
 counts++;
 printf("Ctrl_C Press numbers: %d\n",counts);
}

int main()
{
 int c;
 signal(SIGINT,signal_callback);
 while((c=getchar())!='\n');
 return 0;
}
当运行该程序时,按CTRL+C,则会调用回调函数。

 五、屏蔽信号
所谓屏蔽, 并不是禁止递送信号, 而是暂时阻塞信号的递送,
解除屏蔽后, 信号将被递送, 不会丢失. 相关API为
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);//sigismember()用来测试参数signum 代表的信号是否已加入至参数set信号集里。如果信号集里已有该信号则返回1,否则返回0。

//信号的屏蔽:

int  sigprocmask(int  how,  const  sigset_t *set, sigset_t *oset));

sigprocmask()函数能够根据参数how来实现对信号集的操作,

1)how操作主要有三种:

* SIG_BLOCK 在进程当前阻塞信号集中添加set指向信号集中的信号 mask=mask|set

* SIG_UNBLOCK 如果进程阻塞信号集中包含set指向信号集中的信号,则解除

   对该信号的阻塞  mask=mask & ~set

* SIG_SETMASK 更新进程阻塞信号集为set指向的信号集  mask = set

2)set:如果是非空指针,则更改进程的信号屏蔽字。


3)oset如果是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。

返回0表示成功,-1表示出差。故可以由: sigemptyset(&s);  sigprocmask(SIG_BLOCK,NULL,&s); //block

由&s传出。

未决信号可以由 int sigpending(sigset_t *set),通过set传递出来。获取未决信号。0表示成功,-1失败

六、信号在内核中的表示:

信号递达(Delivery):执行信号的处理动作。

信号未决(Pending):信号从产生到递达之间的状态。

--》进程可以选择阻塞(Block)某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。

 

例子:

#include<sys/types.h>
#include<sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>

void signal_callback(int sigNum)
{
 if(sigNum==SIGRTMIN+2)
 {
  //Unblock the signal 1;
  sigset_t tmp;
  sigemptyset(&tmp);
  sigaddset(&tmp,SIGRTMIN+1);
  sigprocmask(SIG_UNBLOCK,&tmp,0); //block

 

//--》进程可以选择阻塞(Block)某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。因为刚开始时信号1已经被阻塞,因此这个信号将在未决状态。因此当发送信号1即35时将变成未决状态,当发送信号2即36时,如上将信号1进行解阻塞,就会把刚才的信号1执行递达的动作,因此会显示执行printf("recv signal %d\n",sigNum);


 }
 if(sigNum==SIGRTMIN+1)
 {
  printf("recv signal %d\n",sigNum);
 }
}

void printfSigSet(sigset_t *tmp)
{
 int i;
 for( i=0;i<=64;i++)
 {
  if(sigismember(tmp,i))
  {
   putchar('1');
  }
  else
  {
   putchar('0');
  }
  if (i==0)
   putchar('\n');

 }
 printf("----------------------------------\n");

}
int main()
{
 sigset_t p;
 sigset_t s;
 signal(SIGRTMIN+1,signal_callback);
 signal(SIGRTMIN+2,signal_callback);

 //block the signal 1;
 sigemptyset(&p);
 sigaddset(&p,SIGRTMIN+1);
 sigprocmask(SIG_BLOCK,&p,0); //block

 while(1)
 {
  //get which signal is pending
  sigemptyset(&s);
  sigpending(&s);
  printf("pending signal:\n");
  printfSigSet(&s);    


  get which signal is  block
  printf("block signal:\n");
  sigemptyset(&s);
  sigprocmask(SIG_BLOCK,0,&s); //block
  printfSigSet(&s);
  sleep(2);
 }

}

 

运行程序时显示:

pending signal:
1
0000000000000000
0000000000000000
0000000000000000
0000000000000000
----------------------------------
block signal:
1
0000000000000000
0000000000000000
0010000000000000
0000000000000000
----------------------------------

 

当终端发送 kill -35 进程号。时,

pending signal:

1
0000000000000000
0000000000000000
0010000000000000
0000000000000000
----------------------------------
block signal:
1
0000000000000000
0000000000000000
0010000000000000
0000000000000000
----------------------------------

当发送 kill -36 给进程时:

recv signal 35
pending signal:
1
0000000000000000
0000000000000000
0000000000000000
0000000000000000
----------------------------------
block signal:
1
0000000000000000
0000000000000000
0010000000000000
0000000000000000
----------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用的内容,这段引用中包含了一些Vue.js代码和HTML代码,并讨论了换行符和空格在网页中的使用。其中,引用是关于添加和还原换行符的方法,引用是关于在编辑数据时获取详情和使用textarea的示例代码,引用是关于HTML中空格的处理和字符实体的使用。 问题中提到的 是HTML中表示空格的字符实体。HTML通常会自动截取多余的空格,不管你加多少空格,都被看做一个空格。为了在网页中增加空格,可以使用 表示空格。此外,还有其他常用的字符实体,如<表示小于号,>表示大于号,&表示&符号,"表示双引号,等等。 需要注意的是,引用的内容中有一些HTML实体被转义了,所以在描述字符实体时需要参考编码转义后的字符。 根据给定的引用内容,我无法直接回答问题,因为问题中的信息不完整。请提供更具体的问题或补充说明,我将尽力为您提供帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [js+v-html+正则表达式去除所有& nbsp和html标签(& nbsp 换行 )](https://blog.csdn.net/xm_w_xm/article/details/91992754)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [html  特殊字符(转)](https://blog.csdn.net/feiniu5566/article/details/13624619)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值