进程信号

进程信号


  概念:信号就是软件中断,信号就是用于向进程通知某个事件的产生,打断进程当前操作,去处理这个事件。

1.操作系统中信号的种类

进程信号

2.代码演示

Linux中信号的种类: 62种
 1~31: 非可靠信号(有可能造成事件丢失)
 34~64: 可靠信号(不会丢失事件) 信号的生命周期:产生信号->在进程pcb中注册信号->注销账号->处理信号 信号的产生:  硬盘产生:ctrl + c, ctrl + |, ctrl + z;  软件产生:kill命令发送信号给指定进程 kill -signum pid     kill命令杀死一个进程的原理:默认给进程发送了终止信号;
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 int main()
  5 {
  6     while(1){
  7         sleep(1);
  8         printf("---------\n");
  9     }
 10     return 0;
 11 }

进程信号

ctrl + z: 发送一个停止信号, 让程序停止运行
进程并没有退出只是停止运行了
进程信号

程序依然运行在后台;
kill: 给进程发送一个终止信号
进程信号
进程退出
进程信号
进程信号
当使用Ctrl + z, 进程终止之后, 进程就不会再去处理信号了, 所以此时使用kill就不会杀死这个进程.
此时可以使用kill -9, 来杀死这个进程, kill -9 , 就是给进程发送9号命令.

int kill(pid_t pid, int sig);

进程信号

给pid进程发送sig信号

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<signal.h>
  5 int main()
  6 {   
  7     //kill(进程ID, 信号值)
  8     kill(getpid(), SIGINT);
  9     while(1){
 10         printf("-------\n");
 11         sleep(1);
 12     }
 13     return 0;
 14 }

进程信号

程序直接退出;
int raise(int sig);–给进程自身发送一个指定的信号
unsigned int alarm(unsidned int second);–sec秒之后给进程自身发送一个时钟信号–SIGALRM
void abort(void);–给进程自身发送一个SIGABRT信号

3.库函数接口

int sigqueue(pid_t pid, int sig, const union sigval value)

给一个进程发送信号的同时携带一个数据过去

4.信号注册, 注销, 处理

注册: 在进程中注册一个信号让进程知道自己收到了某个信号
修改Pending位图,添加一个信号信息节点

进程信号


注销:将信号信息进程pcb中移除(修改位图,删除节点)
 非可靠:删除节点,修改位图为0
 可靠:删除信号节点,检查链表中是否还有相同节点,没有则修改位图
处理:信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数
 信号的处理方式:
   1.默认处理方式
   2.忽略处理方式
   3.自定义处理方式–用户自己定义信号的处理回调函数

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum:信号值-表示要修改那个信号的处理方式
handler:新的信号处理方式
SIG_DFL-默认; SIG_IGN-忽略; 自定义函数名称
返回值:成功则返回当前信号原来的处理方式,失败则返回SIG_ERR;

5.自定义信号方式的基本使用


演示:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<signal.h>
  5 int main()
  6 {
  7     //signal(信号, 处理方式)
  8     signal(SIGINT, SIG_IGN);
  9     //kill(进程ID, 信号值)
 10     //kill(getpid(), SIGINT);
 11     raise(SIGINT);
 12     while(1){
 13         printf("-------\n");
 14         sleep(1);
 15     }
 16     return 0;
 17 }

进程信号
此时虽然调用raise但程序并未终止
进程信号
因为调用signal将SIGINT信号忽略了;
只能使用Ctrl+\退出信号将进程退出
进程信号

  5 void sigcb(int signo)
  6 {
  7     printf("recv signal:%d\n", signo);
  8 }
 12     signal(SIGINT, sigcb);

Ctrl+c向进程发送一个2号信号
进程信号

6.自定义处理方式的信号捕捉流程

进程信号

7.阻塞

阻塞:信号的阻塞--阻止信号被递达--一个信号被阻塞后,依然收到这个信号会注册,但是暂时不被处理
pcb中有pending位图-未决信号结合; 还有阻塞信号集合, 如果要阻塞一个信号,就是在进程的阻塞信号集合中标记这个信号
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

进程信号


how:操作类型
 SIG_BLOCK–阻塞set集合中的信号 block=block | set
 SIG_UNBLOCK–将set集合中的信号解除阻塞block&=~set
 SIG_SETMASK–将set集合中的信号设置为阻塞集合的信号block = set
返回值:成功返回0;失败返回-1;

上一篇:挖矿木马分析之肉鸡竟是我自己


下一篇:Linux云服务器挖矿病毒(crypto和pnscan)导致CPU占用100%问题解决方案