Linux信号

异步和同步的区别:

同步可以理解成串行执行,每个任务执行有先后顺序;

异步则是并行执行,你做你的事,我干我的事情,相互独立

信号是异步的,一个进程不必通过任何操作来等待信号的到达。事实上,进程也不知道信号到底什么时候到达。一般来说,我们只需要在进程中设置信号相应的处理函数,当有信号到达的时候,由系统异步触发相应的处理函数即可。

产生信号

硬件产生信号:通过终端按键产生信号

ctrl -c是 SIGINT 信号

ctrl -z 是SIGSTOP信号

ctrl -\ 是SIGQUIT信号

输入命令经过系统调用产生信号:kill命令产生信号,调用的是kill()函数 ;

kill函数可以给一个指定的进程发送指定的信号。

raise函数可以给当前进程发送指定的信号(自己给自己发信号)

由软件条件产生信号:调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号,该信号的默认处理动作是终止当前进程。

#include <unistd.h>
#include <stdio.h>
int main(void)
{
 int counter;
 alarm(1);
 for(counter=0; 1; counter++)
 printf("counter=%d ", counter);
 return 0;
}

处理信号

signal()函数对信号进行处理

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

例子1:通过SIG_IGN来忽略SIGINT信号

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

int main()
{
  int i = 0;

  signal(SIGINT, SIG_IGN);  //通过SIG_IGN来忽略SIGINT信号

  do
  {
    write(1,"*", 1);
    sleep(1);
    i++;
  }while(i < 10);
  
  exit(0);
}

例子2:通过自定义的func函数处理信号

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

static void func(int signo)
{
    write(1,"\n ...coming a signal named SIGINT ,func is called\r\n", 50);  
}

int main()
{
  int i = 0;

  signal(SIGINT,func);  

  do
  {
    write(1,"*", 1);
    sleep(1);
    i++;
  }while(i<10);
  
  exit(0);
}

[xuanmiao@192 ~]$ kill -l
 1) SIGHUP   2) SIGINT    **3) SIGQUIT**   4) SIGILL   5) SIGTRAP
 6) SIGABRT   7) SIGBUS   8) SIGFPE   **9) SIGKILL**  10) SIGUSR1
11) SIGSEGV  12) SIGUSR2  13) SIGPIPE  14) SIGALRM  15) SIGTERM
16) SIGSTKFLT  17) SIGCHLD  18) SIGCONT  19) SIGSTOP  20) SIGTSTP
21) SIGTTIN  22) SIGTTOU  23) SIGURG  24) SIGXCPU  25) SIGXFSZ
26) SIGVTALRM  27) SIGPROF  28) SIGWINCH  29) SIGIO  30) SIGPWR
31) SIGSYS  34) SIGRTMIN  35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10  45) SIGRTMIN+11  46) SIGRTMIN+12  47) SIGRTMIN+13
48) SIGRTMIN+14  49) SIGRTMIN+15  50) SIGRTMAX-14  51) SIGRTMAX-13  52) SIGRTMAX-12
53) SIGRTMAX-11  54) SIGRTMAX-10  55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX  

来一段烧脑的代码

#include <stdio.h>

enum { RED, GREEN, BLUE };

void OutputSignal(int sig)
{
        printf("The signal you /'ve input is: ");
        switch(sig)
        {
            case RED:
                   puts("RED!");
                   break;
          case GREEN:
                   puts("GREEN!");
                   break;
          case BLUE:
                   puts("BLUE!");
                   break;
       }
       
       return;
}

void ( *signal( int sig, void (*func)(int) ) ) (int)
{
          puts("Hello, world!");
          func(sig);
          return func;
}

int main(void)
{
           ( *signal (GREEN, &OutputSignal) )  (RED);
           return 0;
}

程序的执行结果:

[xuanmiao@192 Demo]$ ./test 
Hello, world!
The signal you /'ve input is: GREEN!
The signal you /'ve input is: RED!

这里signal函数的声明 void ( *signal( int sig, void (*func)(int)))(int) 可以替换成 

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

对应的函数调用替换成

sighandler_t signal( int sig, sighandler_t func)
{
          puts("Hello, world!");

          func(sig);

          return func;
}

参考文章:

https://www.51cto.com/article/675743.html

posted on 2023-08-05 18:14  轩邈、  阅读(45)  评论(0编辑  收藏  举报

导航