kill,alarm,raise,abort,pause,signal等函数的使用

1.1 kill

kill函数是UNIX和类UNIX操作系统中的一个标准库函数,主要用于向指定进程发送信号。

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signum);

pid_t pid 是进程ID,int signum 是信号的编号。

kill函数的作用是将signum指定的信号发送到pid指定的进程

  • pid > 0:将信号发送给进程ID为pid的进程。
  • pid = 0:将信号发送给当前进程所在的整个进程组中的所有进程。
  • pid < 0:将信号发送给进程组ID等于pid的绝对值的进程组中的所有进程。
  • pid = -1:将信号发送给系统中的所有进程,这个进程组号等于pid的绝对值。

kill函数的成功返回值为0,失败返回值为-1

此外,调用kill函数的进程必须有权限向目标进程发送信号。通常,只有root用户才能向所有进程发送信号,而非root用户只能向与自己用户ID相同的进程发送信号

案例

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
 #include <sys/types.h>
 
  int main()
  {
     pid_t pid;
 
     pid = fork();
     if(pid < 0)
     {
         perror("fail to fork");
         exit(1);
     }
     else if(pid > 0) //父进程的代码区
    {
         while(1)
         {
             printf("This is parent peocess\n");
             sleep(1);
         }
    }
     else //子进程的代码区 
    {
     printf("This is son process\n");
     //子进程在3秒之后,让父进程退出
    sleep(3);
     //使用kill给父进程发送信号,然后父进程接收到信号后直接退出就可以了
    kill(getppid(), SIGINT);
     }
      return 0;
   }

执行结果

 1.2 alarm函数

alarm函数是UNIX和类UNIX系统中的一种标准库函数,它的主要作用是为当前进程设置一个定时器。

当设定时间到达后,定时器会向当前进程发送SIGALRM信号。

这个信号的默认行为是终止进程,但如果进程中有一个已注册的信号处理函数来处理SIGALRM信号,那么进程会根据该函数的逻辑来执行相应的操作

#include <sys/time.h>
unsigned int alarm(unsigned int seconds);

seconds参数

指定了定时器的超时时间,单位是秒。

如果seconds的值为0,那么之前设置的定时器会被取消,并且返回之前定时器剩余的时间。

如果seconds的值为-1,那么返回的是0

alarm函数的返回值有以下几种情况

  • 如果seconds的值为0,返回值也是0。
  • 如果seconds的值大于0,并且在seconds秒内再次调用了alarm函数设置了新的定时器,那么返回值是之前定时器剩余的秒数。
  • 如果seconds的值大于0,并且没有在seconds秒内再次调用alarm函数设置新的定时器,那么返回值是0

案例

#include <stdio.h>
#include <unistd.h>
#int main()
 {
     unsigned int sec; 

     //当执行到alarm之后,代码会接着往下执行,当设定的时间到后,会产生SIGALRM信
     //如果alarm之前没有设置其他闹钟,则返回0,如果之前设置了,则返回之前剩余的
     //如果一个程序中出现多个alarm闹钟,第一个如果没有到达指定的时间就遇到第二个
     //则第一个的闹钟时间清除,按照第二个alarm闹钟的时间继续向下运行
     sec = alarm(5);
     printf("sec = %d\n", sec);
     sleep(3);
     sec = alarm(6);
     printf("sec = %d\n", sec);
     while(1)
     {
         printf("hello world\n");
         sleep(1);
     }
     return 0;
}

执行结果

  1.3 raise函数

raise函数主要用于向当前进程发送一个信号。这个函数的原型如下:

#include <signal.h>
int raise(int sig);

sig参数是你想要发送的信号的名字

。这个函数的工作原理是,当你调用raise函数并传入一个特定的信号名时,它会向当前进程发送这个信号

返回值:  成功:0  

                失败:非0

raise(sig)  等同于   kill(getpid(), sig)

案例

 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
 #include <sys/types.h>
 
  int main(int argc, char const *argv[])
 {
     int num = 0;
 
       while(1)
       {
         printf("hello world\n");
         sleep(1);
         num++;
         //当循环执行5秒后,进程退出
          if(num == 5)
          {
             //使用raise给当前进程本身发送信号
               raise(SIGALRM);
             //等同于kill(getpid(), SIGALRM);
          }
        }
 
     return 0;
  }

执行结果

1.4 abort函数 

abort函数是C语言中的一个标准库函数,其原型定义在<stdlib.h>头文件中

该函数的主要作用是使当前的进程异常终止,即立即停止当前正在执行的程序,而不进行正常的资源回收和清理工作。

 #include <stdlib.h>
 void abort(void);
 功能:向进程发送一个SIGABRT信号,默认情况下进程会退出。
   参数:无
 返回值:无

 注意即使SIGABRT信号被加入阻塞集,一旦进程调用了abort函数,进程也还是会被终止, 且在终止前会刷新缓冲区,关闭文件描述符。

案例

  #include <stdio.h>
  #include <stdlib.h>
  #include <signal.h>
  #include <unistd.h>
  #include <sys/types.h>
 
  int main()
  {
     int num = 0;
 
     while(1)
     {
         printf("hello world\n");
         sleep(1);
         num++;
 
        //当循环执行5秒后,进程退出
          if(num == 5)
          {
             abort();
          }
      }
        return 0;
   }

执行结果

1.5 pause函数

pause函数作用是使当前进程进入等待状态,直到接收到一个信号为止。

这个函数通常用于等待某个特定的事件发生,例如等待用户输入或者等待某个条件满足。

#include <sys/wait.h>

int pause(void);

返回值当有信号产生时,函数返回‐1

案例

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
 #include <sys/types.h>
 
  int main()
  {
     pid_t pid;
     pid = fork();
     if(pid < 0)
     {
        perror("fail to fork");
        exit(1);
     }
     else if(pid > 0) //父进程的代码区
     {
         printf("This is parent peocess\n");
        //使用pause阻塞等待捕捉信号
         pause();
     }
     else //子进程的代码区 
     {
         printf("This is son process\n");
         sleep(3);
         kill(getppid(), SIGINT);//睡眠三秒后杀死父进程
     }
     
         return 0;
  } 

执行结果

1.6 signal函数

signal函数是用于设置一个特定的信号处理函数的标准库函数。

当进程接收到一个信号时,signal函数允许你指定一个函数来处理这个信号。

 #include <signal.h>
  void (*signal(int sig, void (*func)(int)))(int);
 ‐‐>
 typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);
  功能:当进程中产生某一个信号时,对当前信号进行处理
  参数:
 
  sig:指定要处理的信号
    handler:处理方式
    SIG_IGN 当信号产生时,以缺省(忽略)的方式处理
    SIG_DFL 当信号产生时,以当前信号默认的方式处理

func是你想要设置的信号处理函数。信号处理函数必须具有以下形式

void func(int sig);

当信号产生时,通过信号处理函数自定义方式处理,函数名可以随便写,参数表示当前的信号

 返回值: 成功:返回函数地址,该地址为此信号上一次注册的信号处理函数的地址

                 失败:SIG_ERR

1.6.1  signal函数的使用

 #include <stdio.h>
 #include <signal.h>
 #include <unistd.h>
 #include <stdlib.h>
 
  void handler(int sig);
 
  int main(int argc, char const *argv[])
{
     //以默认的方式处理信号
  #if 0
     if(signal(SIGINT, SIG_DFL) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
     if(signal(SIGQUIT, SIG_DFL) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
     if(signal(SIGTSTP, SIG_DFL) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
  #endif
 
     //以忽略的方式来处理信号
  #if 0
     if(signal(SIGINT, SIG_IGN) == SIG_ERR)
     {
        perror("fail to signal");
         exit(1);
     }
    if(signal(SIGQUIT, SIG_IGN) == SIG_ERR)
     {
        perror("fail to signal");
         exit(1);
     }
     if(signal(SIGTSTP, SIG_IGN) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
 
     //注意:SIGKILL和SIGSTOP这两个信号只能以默认的方式处理,不能忽略或者捕捉
    // if(signal(SIGKILL, SIG_IGN) == SIG_ERR)
     // {
     //     perror("fail to signal");
     //     exit(1);
     // }
 
  #endif    

     //以用户自定义方式处理信号
 #if 1
     if(signal(SIGINT, handler) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
     if(signal(SIGQUIT, handler) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
     if(signal(SIGTSTP, handler) == SIG_ERR)
     {
         perror("fail to signal");
         exit(1);
     }
 #endif  

     while(1)
     {
         printf("hello world\n");
         sleep(1);
     }
         return 0;
}
  

  void handler(int sig)
  {
     if(sig == SIGINT)
     {
         printf("SIGINT正在处理\n");
     }
 
     if(sig == SIGQUIT)
     {
        printf("SIGQUIT正在处理\n");
     }
 
     if(sig == SIGTSTP)
     {
         printf("SIGTSTP正在处理\n");
     }
  }

在使用signal函数时,还需要考虑信号处理的同步和互斥问题,以确保程序的正确性和稳定性

  • 34
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值