高编:进程间通信-->信号通信(kill)

应用:异步通信。 中断
1~64;32应用编程。
如何响应:
     Term   Default action is to terminate the process.

      Ign    Default action is to ignore the signal.
      wait

      Core   Default action is to  terminate  the  process  and  dump  core  (see core(5)).
      gdb a.out -c core
      Stop   Default action is to stop the process.

      Cont   Default  action  is  to  continue  the  process  if  it is currently stopped.

一、kill函数 (raise、alarm、pause)

kill             -xx       xxxx
发送进程   信号    接收进程
kill -9 1000
a.out  9 1000

1、发送端

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

    int kill(pid_t pid, int sig);
    功能:通过该函数可以给pid进程发送信号为sig的系统信号。
    参数:pid 要接收信号的进程pid
               sig 当前程序要发送的信号编号 《=== kill  -l
    返回值:成功  0
                  失败  -1;

  #include <stdio.h>
  #include <sys/types.h>
  #include <signal.h>
  #include <stdlib.h>
  
  int main(int argc, const char *argv[])
  {
      printf("Input pid:");
      char buf[10] = {0};
      fgets(buf,sizeof(buf),stdin);                                   
      pid_t pid = atoi(buf);
      int ret = kill(pid,9);
      if (-1 == ret)
      {
         perror("kill fail");
         exit(1);
      }
  
      return 0;
  }

 结果:小窗口终端被关闭


int raise(int sig== kill(getpid(),int sig);
    功能:给进程自己发送sig信号

unsigned int alarm(unsigned int seconds);SIGALAM
    功能:定时由系统给当前进程发送信号,也称为闹钟函数。(闹钟只有一个,定时只有一次有效,但是必须根据代码逻辑是否执行判断。)

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

int main(int argc, char *argv[])
{
    alarm(5);
    while(1)
    {
        printf("i'm working\n");
        sleep(1);
    }
    return 0;
}

int pause(void);
    功能:进程暂停,不再继续执行,除非收到其他信号。

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

int main(int argc, char *argv[])
{
    int i = 0 ;
    while(1)
    {
        printf("i'm working\n");
        sleep(1);
        i++;
        if(5 == i)
        {
            pause();
        }
    }
    return 0;
}


2. 信号  kill  -l  ==>前32个有具体含义的信号

3. 接收端

        每个进程都会对信号作出默认响应,但不是唯一响应。
        一般如下三种处理方式:
        1)默认处理
        2)忽略处理 9,19
        3)自定义处理 9,19 捕获
        以上三种方式的处理需要在如下函数上实现。

    信号注册函数原型:
     
     void ( *signal(int signum, void (*handler)(int)) ) (int);
     typedef void (*sighandler_t)(int);
     ===》void (*xx)(int); == void fun(int);
     ===》xx是 void fun(int) 类型函数的函数指针
     ===》typedef void(*xx)(int)   sighandler_t; ///错误
          typedef int myint;

     ===>sighandler_t signal(int signum, sighandler_t handler);
     ===> signal(int sig, sighandler_t fun);
     ===> signal(int sig, xxx fun);
     ===>fun 有三个宏表示:SIG_DFL 表示默认处理
                                             SIG_IGN 表示忽略处理
                                                 fun     表示自定义处理

 例子:

(1) signal(SIGALRM,handle);

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

int flag = 0;

void handle(int num)
{
    flag = 1;    
}
int main(int argc, char *argv[])
{
    signal(SIGALRM,handle);
    alarm(5);
    while(1)
    {
        if(0 == flag)
        {        
            printf("i'm working\n");
        }
        else
        {  
            printf("i'm resting\n");
        }
        sleep(1);
    }
    return 0;
}

(2) signal(SIGCONT,myhandle);      //SIGCONT--18

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void myhandle(int num)
{
}

int main(int argc, char *argv[])
{
    int i = 0 ;
    signal(SIGCONT,myhandle);
    while(1)
    {
        printf("i'm working pid:%d\n",getpid());
        sleep(1);
        i++;
        if(5 == i)
        {
            pause();
        }
    }
    return 0;
}

按代码5s后停止,若想让代码继续,在另一个终端输入 kill -18 22747

(3) signal(SIGUSR1,handle1); signal(SIGUSR1,SIG_IGN);   // SIGUSR1--10

          signal(SIGUSR2,handle2); signal(SIGUSR2,SIG_DFL);   // SIGUSR2--12

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

void handle1(int num)
{
    static int i = 0;
    printf("老爸叫你\n");
    i++;
    if(3 == i )
    {
        signal(SIGUSR1,SIG_IGN);
    }
}

void handle2(int num)
{
    static int i = 0 ;
    printf("老妈叫你\n");
    i++;
    if(4== i)
    {
        signal(SIGUSR2,SIG_DFL);
    }
}
int main(int argc, char *argv[])
{
    signal(SIGUSR1,handle1);
    signal(SIGUSR2,handle2);
    while(1)    
    {
        printf("i'm playing pid :%d\n",getpid());
        sleep(1);
    }
    return 0;
}

(4)signal_num 

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

void handle1(int num)
{
    if(SIGUSR1== num)
    {
        static int i = 0;
        printf("老爸叫你\n");
        i++;
        if(3 == i)
        {
            signal(SIGUSR1,SIG_IGN);
        }
    }
    if(SIGUSR2 == num)
    {
        static int j = 0 ;
        printf("老妈叫你\n");
        j++;
        if(4 == j)
        {
            signal(SIGUSR2,SIG_DFL);
        }
    }
}
int main(int argc, char *argv[])
{
    signal(SIGUSR1,handle1);
    signal(SIGUSR2,handle1);
    while(1)    
    {
        printf("i'm playing pid :%d\n",getpid());
        sleep(1);
    }
    return 0;
}

运行结果与(3)一样

(5)signal(SIGCHLD,handle);

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <wait.h>
void handle(int num)
{
    pid_t pid = wait(NULL);
    printf("recycle pid %d\n",pid);
}
int main(int argc, char *argv[])
{
    signal(SIGCHLD,handle);
    pid_t pid = fork();
    if(pid>0)
    {
        while(1)
        {
            printf("father processing\n");
            sleep(1);
        }
    }
    else if (0 == pid) 
    {
        sleep(3);    
        printf("child  pid %d\n",getpid());
    }
    else 
    {
        perror("fork");
        exit(1);
    }
    return 0;
}


  • 37
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值