• 【无标题】


    1.处理普通信号

    程序代码:

    1. 1 #include
    2. 2 //定义信号处理函数
    3. 3 void handler(int signo)
    4. 4 {
    5. 5 if(signo==SIGINT)
    6. 6 {
    7. 7 printf("enter ctrl+c\n");
    8. 8 }
    9. 9 }
    10. 10 //处理普通信号
    11. 11 int main(int argc, const char *argv[])
    12. 12 {
    13. 13 /* //忽略SIGINT信号,处理方式SIG_IGN 忽略
    14. 14 if(signal(SIGINT,SIG_IGN)==SIG_ERR)
    15. 15 {
    16. 16 perror("signal error");
    17. 17 return -1;
    18. 18 }
    19. 19 //默认SIGINT,SIG_DFL 默认处理当前信号
    20. 20 if(signal(SIGINT,SIG_DFL)==SIG_ERR)
    21. 21 {
    22. 22 perror("signal error");
    23. 23 return -1;
    24. 24 }*/
    25. 25 //捕获SIGINT信号,处理方式 自定义函数
    26. 26 if(signal(SIGINT,handler)==SIG_ERR)
    27. 27 {
    28. 28 perror("signal error");
    29. 29 return -1;
    30. 30 }
    31. 31 while(1)
    32. 32 {
    33. 33 printf("多活一会\n");
    34. 34 sleep(1);
    35. 35 }
    36. 36 return 0;
    37. 37 }

    运行结果:

    2.捕获或忽略SIGKILL信号(杀死进程)

    程序代码:

    1. 1 #include
    2. 2 //定义信号处理函数
    3. 3 void handler(int signo)
    4. 4 {
    5. 5 if(signo==SIGINT)
    6. 6 {
    7. 7 printf("enter ctrl+c\n");
    8. 8 }
    9. 9 if(signo==SIGKILL)
    10. 10 {
    11. 11 printf("捕获SIGKILL信号\n");
    12. 12 }
    13. 13 }
    14. 14 int main(int argc, const char *argv[])
    15. 15 {
    16. 16 /* //尝试忽略SIGKILL信号
    17. 17 if(signal(SIGKILL,SIG_IGN)==SIG_ERR)
    18. 18 {
    19. 19 perror("signal error");
    20. 20 return -1;
    21. 21 }
    22. 22 //尝试捕获SIGKILL信号
    23. 23 if(signal(SIGKILL,handler)==SIG_ERR)
    24. 24 {
    25. 25 perror("signal error");
    26. 26 return -1;
    27. 27 }*/
    28. 28 //尝试默认操作SIGKILL信号
    29. 29 if(signal(SIGKILL,SIG_DFL)==SIG_ERR)
    30. 30 {
    31. 31 perror("signal error");
    32. 32 return -1;
    33. 33 }
    34. 34 while(1)
    35. 35 {
    36. 36 printf("再活会\n");
    37. 37 sleep(1);
    38. 38 }
    39. 39 return 0;
    40. 40 }

    运行结果:

    3.使用SIGCHLD信号回收僵尸进程,当子进程退出后,子进程给父进程发送SIGCHLD信号,表示子进程的退出

    程序代码:

    1. 1 #include
    2. 2 //信号处理函数
    3. 3 void handler(int signo)
    4. 4 {
    5. 5 if(signo==SIGCHLD)
    6. 6 {
    7. 7 while(waitpid(-1,NULL,WNOHANG)>0);
    8. 8 }
    9. 9 }
    10. 10 int main(int argc, const char *argv[])
    11. 11 {
    12. 12 //将子进程退出时发出的SIGCHLD信号捕获
    13. 13 if(signal(SIGCHLD,handler)==SIG_ERR)
    14. 14 {
    15. 15 perror("signal error");
    16. 16 return -1;
    17. 17 }
    18. 18 //创建僵尸进程
    19. 19 for(int i=0;i<6;i++)
    20. 20 {
    21. 21 if(fork()==0)
    22. 22 {
    23. 23 sleep(1);
    24. 24 exit(EXIT_SUCCESS);
    25. 25 }
    26. 26 }
    27. 27 while(1);
    28. 28 return 0;
    29. 29 }

    运行结果:

    4.SIGALRM信号,创建定时器,模拟出牌

    程序代码:

    1. 1 #include
    2. 2 //定义信号处理函数
    3. 3 void handler(int signo)
    4. 4 {
    5. 5 if(signo==SIGALRM)
    6. 6 {
    7. 7 printf("系统随机出一张:\n");
    8. 8 alarm(5);
    9. 9 }
    10. 10 }
    11. 11 int main(int argc, const char *argv[])
    12. 12 {
    13. 13 //捕获SIGALRM信号
    14. 14 if(signal(SIGALRM,handler)==SIG_ERR)
    15. 15 {
    16. 16 perror("signal error");
    17. 17 return -1;
    18. 18 }
    19. 19 //启动定时器
    20. 20 alarm(5);
    21. 21 char ch=0;
    22. 22 while(1)
    23. 23 {
    24. 24 scanf("%c",&ch);
    25. 25 getchar();
    26. 26 printf("出了个:%c\n",ch);
    27. 27 alarm(5);
    28. 28 }
    29. 29 return 0;
    30. 30 }

    运行结果:

    5.验证发送信号函数

    程序代码:

    1. 1 #include
    2. 2 void handler(int signo)
    3. 3 {
    4. 4 if(signo==SIGUSR1)
    5. 5 {
    6. 6 printf("活不了啦\n");
    7. 7 raise(SIGKILL);//向自己发送一个死亡信号
    8. 8 }
    9. 9 }
    10. 10 int main(int argc, const char *argv[])
    11. 11 {
    12. 12 //将SIGUSR1信号绑定
    13. 13 if(signal(SIGUSR1,handler)==SIG_ERR)
    14. 14 {
    15. 15 perror("signal error");
    16. 16 return -1;
    17. 17 }
    18. 18 //创建两个进程
    19. 19 pid_t pid=fork();
    20. 20 if(pid>0)
    21. 21 {
    22. 22 //父进程
    23. 23 while(1)
    24. 24 {
    25. 25 printf("多活一会\n");
    26. 26 sleep(1);
    27. 27 }
    28. 28 }else if(pid==0)
    29. 29 {
    30. 30 //子进程
    31. 31 sleep(5);
    32. 32 //向父进程发送信号,让父进程退出
    33. 33 printf("苍天已死,黄天登立\n");
    34. 34 kill(getppid(),SIGUSR1);
    35. 35 while(1)
    36. 36 {
    37. 37 printf("岁在甲子,天下大吉\n");
    38. 38 sleep(1);
    39. 39 }
    40. 40 }
    41. 41 return 0;
    42. 42 }

    运行结果:

    6.消息队列,msgsnd向消息队列存放消息

    程序代码:

    msgsnd.c:

    1. 1 #include
    2. 2 //定义一个消息类型
    3. 3 struct msgbuf
    4. 4 {
    5. 5 long mtype;//消息类型
    6. 6 char mtext[1024];//消息正文
    7. 7 };
    8. 8 //定义一个宏,表示消息正文大小
    9. 9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
    10. 10 int main(int argc, const char *argv[])
    11. 11 {
    12. 12 //创建key值
    13. 13 key_t key=0;
    14. 14 if((key=ftok("/",'k'))==-1)
    15. 15 {
    16. 16 perror("ftok error");
    17. 17 return -1;
    18. 18 }
    19. 19 printf("ftok success key=%#x\n",key);
    20. 20 //根据key值创建一个消息队列
    21. 21 int msqid=-1;
    22. 22 if((msqid=msgget(key,IPC_CREAT|0664))==-1)
    23. 23 {
    24. 24 perror("msgget error");
    25. 25 return -1;
    26. 26 }
    27. 27 printf("msgget success msqid=%d\n",msqid);
    28. 28 //定义一个消息
    29. 29 struct msgbuf sbuf;
    30. 30 while(1)
    31. 31 {
    32. 32 //清空正文容器
    33. 33 bzero(sbuf.mtext,sizeof(sbuf.mtext));
    34. 34 printf("请输入当前消息类型:");
    35. 35 scanf("%ld",&sbuf.mtype);
    36. 36 getchar();//回收垃圾字符
    37. 37 printf("请输入消息正文:");
    38. 38 fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);
    39. 39 sbuf.mtext[strlen(sbuf.mtext)-1]=0;
    40. 40 //将消息存放队列中
    41. 41 msgsnd(msqid,&sbuf,MSGSIZE,0);
    42. 42 printf("发送成功\n");
    43. 43 if(strcmp(sbuf.mtext,"quit")==0)
    44. 44 break;
    45. 45 }
    46. 46 return 0;
    47. 47 }

    msgrcv.c:

    1. 1 #include
    2. 2 //定义一个消息类型
    3. 3 struct msgbuf
    4. 4 {
    5. 5 long type;//消息类型
    6. 6 char mtext[1024];//消息正文
    7. 7 };
    8. 8 //定义一个宏,表示消息正文大小
    9. 9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
    10. 10 int main(int argc, const char *argv[])
    11. 11 {
    12. 12 //创建一个key值
    13. 13 key_t key=0;
    14. 14 if((key=ftok("/",'k'))==-1)
    15. 15 {
    16. 16 perror("ftok error");
    17. 17 return -1;
    18. 18 }
    19. 19 printf("ftok success key=%#x\n",key);
    20. 20 //根据key值创建一个消息队列
    21. 21 int msqid=-1;
    22. 22 if((msqid=msgget(key,IPC_CREAT|0664))==-1)
    23. 23 {
    24. 24 perror("msgget error");
    25. 25 return -1;
    26. 26 }
    27. 27 printf("msgget success msqid=%d\n",msqid);
    28. 28 //定义一个消息
    29. 29 struct msgbuf rbuf;
    30. 30 while(1)
    31. 31 {
    32. 32 //清空容器
    33. 33 bzero(rbuf.mtext,sizeof(rbuf.mtext));
    34. 34 //从消息队列中读取一个消息
    35. 35 //msgrcv(msqid,&rbuf,MSGSIZE,0,0);
    36. 36 //第一个0:表示一直读取队列中第一个消息
    37. 37 //第二个0:表示阻塞读取
    38. 38 msgrcv(msqid,&rbuf,MSGSIZE,1,0);//只接受类型为1
    39. 39 printf("收到消息:%s\n",rbuf.mtext);
    40. 40 if(strcmp(rbuf.mtext,"quit")==0)
    41. 41 break;
    42. 42 }
    43. 43 //删除消息队列
    44. 44 if(msgctl(msqid,IPC_RMID,NULL)!=0)
    45. 45 {
    46. 46 perror("msgctl error");
    47. 47 return -1;
    48. 48 }
    49. 49 return 0;
    50. 50 }

    运行结果:

    7.使用消息队列完成两个进程间相互通信

    程序代码:

    msgsend1:

    1. 1 #include
    2. 2 //定义一个消息类型
    3. 3 struct msgbuf
    4. 4 {
    5. 5 long mtype;
    6. 6 char mtest[1024];
    7. 7 };
    8. 8
    9. 9 //定义宏,消息正文大小
    10. 10 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
    11. 11 int main(int argc, const char *argv[])
    12. 12 {
    13. 13 //1、创建key值
    14. 14 key_t key=0;
    15. 15 if((key=ftok("/",'k'))==-1){
    16. 16 perror("ftok error");
    17. 17 return -1;
    18. 18 }
    19. 19 //根据key值创建一个消息队列
    20. 20 int msqid=-1;
    21. 21 if((msqid=msgget(key,IPC_CREAT|0664))==-1){
    22. 22 perror("msgget error");
    23. 23 return -1;
    24. 24 }
    25. 25 //创建一个子进程
    26. 26 pid_t pid=fork();
    27. 27
    28. 28 if(pid>0){
    29. 29 //父进程向消息队列中写入类型为1的消息正文
    30. 30 //定义一个消息
    31. 31 struct msgbuf sbuf;
    32. 32 sbuf.mtype=1;
    33. 33 while(1)
    34. 34 {
    35. 35 //清空容器
    36. 36 bzero(sbuf.mtest,sizeof(sbuf.mtest));
    37. 37
    38. 38 printf("发送的消息:");
    39. 39 fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
    40. 40 sbuf.mtest[strlen(sbuf.mtest)-1]='\0';
    41. 41
    42. 42 //将消息存放到消息队列
    43. 43 msgsnd(msqid,&sbuf,MSGSIZE,0);
    44. 44 printf("发送成功\n");
    45. 45
    46. 46 if(strcmp(sbuf.mtest,"quit")==0){
    47. 47 break;
    48. 48 }
    49. 49 }
    50. 50 wait(NULL);
    51. 51 }else if(pid==0){
    52. 52 //子进程从消息队列中取出类型为2的消息正文
    53. 53 //定义一个消息
    54. 54 struct msgbuf rbuf;
    55. 55
    56. 56 while(1)
    57. 57 {
    58. 58 //清空容器
    59. 59 bzero(rbuf.mtest,sizeof(rbuf.mtest));
    60. 60
    61. 61 //从消息队列中读取类型为2的消息正文
    62. 62 msgrcv(msqid,&rbuf,MSGSIZE,2,0);
    63. 63
    64. 64 printf("收到的消息为:%s\n",rbuf.mtest);
    65. 65 if(strcmp(rbuf.mtest,"quit")==0){
    66. 66 break;
    67. 67 }
    68. 68 }
    69. 69 exit(EXIT_SUCCESS);
    70. 70 }else{
    71. 71 perror("fork error");
    72. 72 return -1;
    73. 73 }
    74. 74
    75. 75 return 0;
    76. 76 }

    msgrcv1:

    1. 1 #include
    2. 2 //定义一个消息类型
    3. 3 struct msgbuf
    4. 4 {
    5. 5 long mtype;
    6. 6 char mtest[1024];
    7. 7 };
    8. 8 //宏表示消息正文大小
    9. 9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
    10. 10 int main(int argc, const char *argv[])
    11. 11 {
    12. 12 //1、创建key值
    13. 13 key_t key=0;
    14. 14 if((key=ftok("/",'k'))==-1){
    15. 15 perror("ftok error");
    16. 16 return -1;
    17. 17 }
    18. 18 //根据key值创建一个消息队列
    19. 19 int msqid=-1;
    20. 20 if((msqid=msgget(key,IPC_CREAT|0664))==-1){
    21. 21 perror("msgget error");
    22. 22 return -1;
    23. 23 }
    24. 24 //创建一个子进程
    25. 25 pid_t pid=fork();
    26. 26
    27. 27 if(pid>0){
    28. 28 //父进程从消息队列中取出类型为1的消息正文
    29. 29 //定义一个消息
    30. 30 struct msgbuf rbuf;
    31. 31 while(1)
    32. 32 {
    33. 33 //清空容器
    34. 34 bzero(rbuf.mtest,sizeof(rbuf.mtest));
    35. 35
    36. 36 //从消息队列中读取类型为1的消息正文
    37. 37 msgrcv(msqid,&rbuf,MSGSIZE,1,0);
    38. 38
    39. 39 printf("收到的消息为:%s\n",rbuf.mtest);
    40. 40 if(strcmp(rbuf.mtest,"quit")==0){
    41. 41 break;
    42. 42 }
    43. 43 }
    44. 44 wait(NULL);
    45. 45 }else if(pid==0){
    46. 46 //子进程向消息队列中写入类型为2的消息正文
    47. 47 //定义一个消息
    48. 48 struct msgbuf sbuf;
    49. 49 sbuf.mtype=2;
    50. 50 while(1)
    51. 51 {
    52. 52 //清空容器
    53. 53 bzero(sbuf.mtest,sizeof(sbuf.mtest));
    54. 54
    55. 55 printf("发送的消息:");
    56. 56 fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
    57. 57 sbuf.mtest[strlen(sbuf.mtest)-1]='\0';
    58. 58
    59. 59 //将消息存放到消息队列
    60. 60 msgsnd(msqid,&sbuf,MSGSIZE,0);
    61. 61 printf("发送成功\n");
    62. 62
    63. 63 if(strcmp(sbuf.mtest,"quit")==0){
    64. 64 break;
    65. 65 }
    66. 66 }
    67. 67 exit(EXIT_SUCCESS);
    68. 68 }else{
    69. 69 perror("fork error");
    70. 70 return -1;
    71. 71 }
    72. 72
    73. 73 return 0;
    74. 74 }

    运行结果:

  • 相关阅读:
    TCP协议 - 三次握手 - 四次挥手
    Win10 固定IP地址方法
    【python学习】基础篇-常用模块-argparse模块:用于解析命令行参数和选项
    k8s--基础--28.5--ceph--k8s对接ceph rbd
    程序员合作保密协议
    Spring 08: AOP面向切面编程 + 手写AOP框架
    降压转换器 LM73606QRNPRQ1 汽车 开关稳压器 30WQFN
    【算法优选】双指针专题——壹
    图的存储 —— 邻接矩阵
    建立数据科学基础设施的绝佳指南 数据工程师都该人手一册
  • 原文地址:https://blog.csdn.net/2301_81513928/article/details/136286514