当前位置:   article > 正文

Linuxc/c++之信号基础_linux c语言 信号

linux c语言 信号

目录

1. 信号的本质

2. 信号的产生

3. 信号的处理过程

4. 信号的分类

5. 信号注册与信号发送

6. 信号屏蔽


1. 信号的本质

信号的本质就是整数,是用户模式下用来模拟硬件中断的一种方式。

硬件中断(真正中断):物理层面

软件中断(模拟中断):模拟

2. 信号的产生

  1.  硬件产生
  2.  内核产生
  3.  进程产生

3. 信号的处理过程

如果当前进程A正在运行,然后内核,硬件或者其它进程发送信号给进程A

进程A接收到信号之后:

1. 直接做信号本身规定的对应处理(例如SIGINT就是关闭进程(ctrl + C))

2. 做事先注册好的信号处理(信号注册函数signal(信号,处理函数))

3. 信号被屏蔽,等待信号屏蔽解除然后做出相应处理

4. 信号的分类

4.1 Linux提供的64个信号

kill -l

4.2 按照可靠性分类

不可靠信号:非实时性的信号  由UNIX提供的       1  --- 31

可靠信号:实时性的信号   后来扩充的                 32 --- 64

4.3 按照类型分

标准信号:操作系统提供的信号

自定义信号:用户自定义的信号    SIG_USR

5. 信号注册与信号发送

        5.1 信号注册

                5.1.1 signal函数

                不含signal 函数的一个进程,      使用Ctrl  +  C 或者  Ctrl   + \  可以结束当前进程

                标准信号处理函数

                typedef void (*sighandler_t)(int);

                sighandler_t signal(int signum,sighandler_t handler);

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <signal.h>
  4. int main(){
  5. printf("pid: %d\n",getpid());
  6. int n = 0;
  7. while(1){
  8. printf(">> %d\n",n++);
  9. sleep(1);
  10. }
  11. return 0;
  12. }

 

         使用signal函数注册SIGINT信号后, 当注册SIGINT信号之后, 使用Ctrl + C 发送SIGINT信号就会调用自定义的信号处理函数

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <signal.h>
  4. //SIGINT信号处理函数
  5. void hand(int val){
  6. printf("val---%d\t想干掉我,没门!\n",val); //val 为 signum SIGINT的值为2
  7. }
  8. int main(){
  9. signal(SIGINT,hand); //注册信号处理(信号自己处理,不交给操作系统处理)
  10. printf("pid: %d\n",getpid());
  11. int n = 0;
  12. while(1){
  13. printf(">> %d\n",n++);
  14. sleep(1);
  15. }
  16. return 0;
  17. }

 

                5.1.2 sigaction函数(高级信号注册函数)

                        sigaction()高级信号注册函数对应sigqueue()高级信号发送函数

                        int sigaction(int signum, const struct sigaction* act, struct sigaction* oldact)

                        参数一: 信号的id(例如SIGINT信号的signum 为 2)

                        参数二: 新的信号处理方式

                        参数三: 旧的信号处理方式

                        struct sigaction{

                                void (*sa_handler)(int);    //原来的信号处理函数

                                void (*sa_sigaction)(int, siginfo_t *,void *);  //高级的信号处理函数

                                sigset_t   sa_mask;     //信号屏蔽

                                int  sa_flags;                //使用原来的还是高级的信号处理函数

                                void (*sa_restorer)(void);   //目前未使用

                        };

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <sys/types.h>
  6. void hand(int n){
  7. printf("基本的信号处理函数!\n");
  8. }
  9. //参数1 信号 参数2 信号的一些信息(信号发送者给传入的数据) 参数3 注册信号传入的参数
  10. void handler(int n,siginfo_t* siginfo,void* arg){
  11. printf("高级的信号处理函数!\n");
  12. printf("n:%d,msg:%d\n",n,siginfo->si_int);
  13. }
  14. int main(){
  15. printf("pid--->%d\n",getpid());
  16. struct sigaction act = {0};
  17. struct sigaction oldAct = {0};
  18. act.sa_handler = hand; //信号处理函数
  19. act.sa_sigaction = handler; //高级信号处理函数
  20. //sa_mask //信号屏蔽
  21. //*sa_restorer //目前未使用
  22. act.sa_flags = SA_SIGINFO; //sigaction替换handler
  23. //SIGINT
  24. sigaction(2,&act,&oldAct); //注册高级信号处理
  25. //参数三作为返回值存在的
  26. int n = 0;
  27. while(1){
  28. printf(">>> %d\n",n++);
  29. sleep(1);
  30. }
  31. return 0;
  32. }

        5.2 信号发送

                5.2.1 kill函数

                        kill(pid,sid);    参数1: 进程id  参数二: 信号  

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. //信号的发送之kill函数
  4. int aton(char* str){
  5. int num = 0;
  6. while(*str){
  7. num = num * 10 + (*str-'0');
  8. str++;
  9. }
  10. return num;
  11. }
  12. int main(int argc,char* argv[]){
  13. int pid = aton(argv[1]); //进程id
  14. int sid = aton(argv[2]); //信号id 2(SIGINT信号)
  15. printf("%d %d",pid,sid);
  16. // 进程id 信号id
  17. kill(pid,sid);
  18. return 0;
  19. }

 

                5.2.2 sigqueue函数(高级信号发送函数)

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <sys/types.h>
  6. int aton(char* str){
  7. int num = 0;
  8. while(*str){
  9. num = num * 10 + (*str-'0');
  10. str++;
  11. }
  12. return num;
  13. }
  14. int main(int argc,char* argv[]){
  15. int pid = aton(argv[1]);
  16. int sid = aton(argv[2]);
  17. union sigval u;
  18. u.sival_int = 6666666;
  19. sigqueue(pid,sid,u);
  20. return 0;
  21. }

 

                5.2.3 kill命令

                        kill   sid   -s   pid

                                sid:  信号id       pid:  进程id

                         

6. 信号屏蔽

        int sigprocmask(int how, const sigset_t* set, sigset_t* oldset);

        参数一: 是否屏蔽(或者其它的操作)  SIG_BLOCK(屏蔽)  SIG_UNBLOCK(不屏蔽)

        参数二: 指向信号集的指针,新设的信号集

        参数三: 指向信号集的指针,原来的信号集

        返回值: 成功返回 0

        

        int sigemptyset(sigset_t* set);  //信号集清空函数

        int sigfillset(sigset_t* set);   //将所有的信号添加进去

        int sigaddset(sigset_t* set, int signum);  //向信号集中添加一个信号

        int sigdelset(sigset_t* set,int signum);   //删除信号集中的一个信号

        int sigismember(const sigset_t* set, int signum); //判断某个信号是否在信号集中

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <signal.h>
  4. #include <sys/types.h>
  5. void hand(int n){
  6. printf("基本的信号处理函数!\n");
  7. }
  8. int main(){
  9. printf("pid: %d\n",getpid());
  10. sigset_t set,oldSet;
  11. sigemptyset(&set); //清空信号集
  12. sigaddset(&set,2);
  13. //5秒钟不设置信号屏蔽
  14. signal(2,hand);
  15. sleep(5);
  16. //设置信号屏蔽20秒
  17. //sigismember 判断信号是否在信号集中
  18. int ret;
  19. if(1 == sigismember(&set,2)){
  20. printf("设置信号屏蔽!\n");
  21. ret = sigprocmask(SIG_BLOCK,&set,&oldSet);
  22. //参数1 屏蔽还是解除屏蔽
  23. //参数3为返回值 返回old信号集
  24. if(0 == ret)
  25. printf("设置信号屏蔽成功!\n");
  26. else
  27. printf("设置信号屏蔽失败!\n");
  28. }
  29. sleep(20);
  30. //解除信号屏蔽
  31. if(1 == sigismember(&set,2)){
  32. printf("解除信号屏蔽!\n");
  33. ret = sigprocmask(SIG_UNBLOCK,&set,&oldSet);
  34. if(0 == ret)
  35. printf("解除信号屏蔽成功!\n");
  36. else
  37. printf("解除信号屏蔽失败!\n");
  38. }
  39. while(1);
  40. return 0;
  41. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/458596
推荐阅读
相关标签
  

闽ICP备14008679号