Linux_7 信号(传递控制命令)

1.信号基本概念       

      Linux系统上运行有多个进程,其中许多都是独立运行。然而,有些进程必须相互合作以达成预期目的,因此彼此间需要通信和同步机制。
      读写磁盘文件中的信息是进程间通信的方法之一。可是,对许多程序来说,这种方法既慢又缺乏灵活性。因此,像所有现代UNIX实现那样,Linux 也提供了丰富的进程间通信(IPC)机制,如下所示。

在 Linux 系统上输入 kill -l 来列出系统使用的信号,下面是我提供的一些信号

$ 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     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

信号:内核与应用进程之间,以及应用进程与应用进程之间传递控制命令的方法

2.举例

 例子1

sig_kill.c

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>

int main(void)
{
     pid_t pid;
     pid = fork();       // 创建进程

     if(pid > 0)         // 父进程
     {
         sleep(10);
         kill(pid, SIGKILL);  // 父进程向子进程发送kill信号,结束子进程
     }
     else if(pid == 0)   // 子进程
     {
         int i = 0;
         printf("child  process id = %d\n", getpid());  // 子进程id号
         while(1)
         {
              printf("count to %d\n", ++i);
              sleep(1);
         }
     }
     else
         perror("fork");
     return 0;

}

signal函数----重新定义信号

 例子2

signal.c 

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<wait.h>

void function(int signo);

int main(void)
{
       int i = 0;
       printf("pid = %d\n", getpid()); // 该进程ID号
    
       signal(SIGINT, function);
       signal(SIGKILL, function);

       while(1)
       {
           printf("count to %d\n", ++i);
           sleep(1);
       }

       return 0;
}

void function(int signo)
{
       if(signo == SIGINT)    // 可以重新定义的信号
       { 
            printf("you have just triggered a ctrl+c operation.\n");
            exit(1);  
       }
       else if(signo == SIGKILL)   // 不可修改的信号
            printf("trig a SIGKILL signal.\n");
}

kill.c 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>

int main(int argc, char *argv[])
{
     kill(atoi(argv[1]), SIGKILL);  // 转化为整数
     return 0;
}

编译   gcc  kill.c  -o   kill
运行   ./kill  3160          (3160为signal.c的进程号) 无法实现,因为SIGKILL无法重新定义

例子3

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<wait.h>

//自定义的信号处理函数
void My_Fun(int sig)
{
    if(SIGRTMIN == sig)
    {
        printf("MIN!\n");
    }
    if(SIGRTMAX == sig)
    {
        printf("MAX!\n");
    }
}

int main()
{
    //注册信号处理函数
    signal(SIGRTMIN,My_Fun);
    signal(SIGRTMAX,My_Fun);
    //挂起10s
    sleep(3);
    //发出信号
    kill(getpid(),SIGRTMIN);    //getpid()函数用于获取当前进程的pid.
    kill(getpid(),SIGRTMAX);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44177768/article/details/128649959