1.处理普通信号
程序代码:
1 #include<myhead.h>
2 //定义信号处理函数
3 void handler(int signo)
4 {
5 if(signo==SIGINT)
6 {
7 printf("enter ctrl+c\n");
8 }
9 }
10 //处理普通信号
11 int main(int argc, const char *argv[])
12 {
13 /* //忽略SIGINT信号,处理方式SIG_IGN 忽略
14 if(signal(SIGINT,SIG_IGN)==SIG_ERR)
15 {
16 perror("signal error");
17 return -1;
18 }
19 //默认SIGINT,SIG_DFL 默认处理当前信号
20 if(signal(SIGINT,SIG_DFL)==SIG_ERR)
21 {
22 perror("signal error");
23 return -1;
24 }*/
25 //捕获SIGINT信号,处理方式 自定义函数
26 if(signal(SIGINT,handler)==SIG_ERR)
27 {
28 perror("signal error");
29 return -1;
30 }
31 while(1)
32 {
33 printf("多活一会\n");
34 sleep(1);
35 }
36 return 0;
37 }
运行结果:
2.捕获或忽略SIGKILL信号(杀死进程)
程序代码:
1 #include<myhead.h>
2 //定义信号处理函数
3 void handler(int signo)
4 {
5 if(signo==SIGINT)
6 {
7 printf("enter ctrl+c\n");
8 }
9 if(signo==SIGKILL)
10 {
11 printf("捕获SIGKILL信号\n");
12 }
13 }
14 int main(int argc, const char *argv[])
15 {
16 /* //尝试忽略SIGKILL信号
17 if(signal(SIGKILL,SIG_IGN)==SIG_ERR)
18 {
19 perror("signal error");
20 return -1;
21 }
22 //尝试捕获SIGKILL信号
23 if(signal(SIGKILL,handler)==SIG_ERR)
24 {
25 perror("signal error");
26 return -1;
27 }*/
28 //尝试默认操作SIGKILL信号
29 if(signal(SIGKILL,SIG_DFL)==SIG_ERR)
30 {
31 perror("signal error");
32 return -1;
33 }
34 while(1)
35 {
36 printf("再活会\n");
37 sleep(1);
38 }
39 return 0;
40 }
运行结果:
3.使用SIGCHLD信号回收僵尸进程,当子进程退出后,子进程给父进程发送SIGCHLD信号,表示子进程的退出
程序代码:
1 #include<myhead.h>
2 //信号处理函数
3 void handler(int signo)
4 {
5 if(signo==SIGCHLD)
6 {
7 while(waitpid(-1,NULL,WNOHANG)>0);
8 }
9 }
10 int main(int argc, const char *argv[])
11 {
12 //将子进程退出时发出的SIGCHLD信号捕获
13 if(signal(SIGCHLD,handler)==SIG_ERR)
14 {
15 perror("signal error");
16 return -1;
17 }
18 //创建僵尸进程
19 for(int i=0;i<6;i++)
20 {
21 if(fork()==0)
22 {
23 sleep(1);
24 exit(EXIT_SUCCESS);
25 }
26 }
27 while(1);
28 return 0;
29 }
运行结果:
4.SIGALRM信号,创建定时器,模拟出牌
程序代码:
1 #include<myhead.h>
2 //定义信号处理函数
3 void handler(int signo)
4 {
5 if(signo==SIGALRM)
6 {
7 printf("系统随机出一张:\n");
8 alarm(5);
9 }
10 }
11 int main(int argc, const char *argv[])
12 {
13 //捕获SIGALRM信号
14 if(signal(SIGALRM,handler)==SIG_ERR)
15 {
16 perror("signal error");
17 return -1;
18 }
19 //启动定时器
20 alarm(5);
21 char ch=0;
22 while(1)
23 {
24 scanf("%c",&ch);
25 getchar();
26 printf("出了个:%c\n",ch);
27 alarm(5);
28 }
29 return 0;
30 }
运行结果:
5.验证发送信号函数
程序代码:
1 #include<myhead.h>
2 void handler(int signo)
3 {
4 if(signo==SIGUSR1)
5 {
6 printf("活不了啦\n");
7 raise(SIGKILL);//向自己发送一个死亡信号
8 }
9 }
10 int main(int argc, const char *argv[])
11 {
12 //将SIGUSR1信号绑定
13 if(signal(SIGUSR1,handler)==SIG_ERR)
14 {
15 perror("signal error");
16 return -1;
17 }
18 //创建两个进程
19 pid_t pid=fork();
20 if(pid>0)
21 {
22 //父进程
23 while(1)
24 {
25 printf("多活一会\n");
26 sleep(1);
27 }
28 }else if(pid==0)
29 {
30 //子进程
31 sleep(5);
32 //向父进程发送信号,让父进程退出
33 printf("苍天已死,黄天登立\n");
34 kill(getppid(),SIGUSR1);
35 while(1)
36 {
37 printf("岁在甲子,天下大吉\n");
38 sleep(1);
39 }
40 }
41 return 0;
42 }
运行结果:
6.消息队列,msgsnd向消息队列存放消息
程序代码:
msgsnd.c:
1 #include<myhead.h>
2 //定义一个消息类型
3 struct msgbuf
4 {
5 long mtype;//消息类型
6 char mtext[1024];//消息正文
7 };
8 //定义一个宏,表示消息正文大小
9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
10 int main(int argc, const char *argv[])
11 {
12 //创建key值
13 key_t key=0;
14 if((key=ftok("/",'k'))==-1)
15 {
16 perror("ftok error");
17 return -1;
18 }
19 printf("ftok success key=%#x\n",key);
20 //根据key值创建一个消息队列
21 int msqid=-1;
22 if((msqid=msgget(key,IPC_CREAT|0664))==-1)
23 {
24 perror("msgget error");
25 return -1;
26 }
27 printf("msgget success msqid=%d\n",msqid);
28 //定义一个消息
29 struct msgbuf sbuf;
30 while(1)
31 {
32 //清空正文容器
33 bzero(sbuf.mtext,sizeof(sbuf.mtext));
34 printf("请输入当前消息类型:");
35 scanf("%ld",&sbuf.mtype);
36 getchar();//回收垃圾字符
37 printf("请输入消息正文:");
38 fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);
39 sbuf.mtext[strlen(sbuf.mtext)-1]=0;
40 //将消息存放队列中
41 msgsnd(msqid,&sbuf,MSGSIZE,0);
42 printf("发送成功\n");
43 if(strcmp(sbuf.mtext,"quit")==0)
44 break;
45 }
46 return 0;
47 }
msgrcv.c:
1 #include<myhead.h>
2 //定义一个消息类型
3 struct msgbuf
4 {
5 long type;//消息类型
6 char mtext[1024];//消息正文
7 };
8 //定义一个宏,表示消息正文大小
9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
10 int main(int argc, const char *argv[])
11 {
12 //创建一个key值
13 key_t key=0;
14 if((key=ftok("/",'k'))==-1)
15 {
16 perror("ftok error");
17 return -1;
18 }
19 printf("ftok success key=%#x\n",key);
20 //根据key值创建一个消息队列
21 int msqid=-1;
22 if((msqid=msgget(key,IPC_CREAT|0664))==-1)
23 {
24 perror("msgget error");
25 return -1;
26 }
27 printf("msgget success msqid=%d\n",msqid);
28 //定义一个消息
29 struct msgbuf rbuf;
30 while(1)
31 {
32 //清空容器
33 bzero(rbuf.mtext,sizeof(rbuf.mtext));
34 //从消息队列中读取一个消息
35 //msgrcv(msqid,&rbuf,MSGSIZE,0,0);
36 //第一个0:表示一直读取队列中第一个消息
37 //第二个0:表示阻塞读取
38 msgrcv(msqid,&rbuf,MSGSIZE,1,0);//只接受类型为1
39 printf("收到消息:%s\n",rbuf.mtext);
40 if(strcmp(rbuf.mtext,"quit")==0)
41 break;
42 }
43 //删除消息队列
44 if(msgctl(msqid,IPC_RMID,NULL)!=0)
45 {
46 perror("msgctl error");
47 return -1;
48 }
49 return 0;
50 }
运行结果:
7.使用消息队列完成两个进程间相互通信
程序代码:
msgsend1:
1 #include <myhead.h>
2 //定义一个消息类型
3 struct msgbuf
4 {
5 long mtype;
6 char mtest[1024];
7 };
8
9 //定义宏,消息正文大小
10 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
11 int main(int argc, const char *argv[])
12 {
13 //1、创建key值
14 key_t key=0;
15 if((key=ftok("/",'k'))==-1){
16 perror("ftok error");
17 return -1;
18 }
19 //根据key值创建一个消息队列
20 int msqid=-1;
21 if((msqid=msgget(key,IPC_CREAT|0664))==-1){
22 perror("msgget error");
23 return -1;
24 }
25 //创建一个子进程
26 pid_t pid=fork();
27
28 if(pid>0){
29 //父进程向消息队列中写入类型为1的消息正文
30 //定义一个消息
31 struct msgbuf sbuf;
32 sbuf.mtype=1;
33 while(1)
34 {
35 //清空容器
36 bzero(sbuf.mtest,sizeof(sbuf.mtest));
37
38 printf("发送的消息:");
39 fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
40 sbuf.mtest[strlen(sbuf.mtest)-1]='\0';
41
42 //将消息存放到消息队列
43 msgsnd(msqid,&sbuf,MSGSIZE,0);
44 printf("发送成功\n");
45
46 if(strcmp(sbuf.mtest,"quit")==0){
47 break;
48 }
49 }
50 wait(NULL);
51 }else if(pid==0){
52 //子进程从消息队列中取出类型为2的消息正文
53 //定义一个消息
54 struct msgbuf rbuf;
55
56 while(1)
57 {
58 //清空容器
59 bzero(rbuf.mtest,sizeof(rbuf.mtest));
60
61 //从消息队列中读取类型为2的消息正文
62 msgrcv(msqid,&rbuf,MSGSIZE,2,0);
63
64 printf("收到的消息为:%s\n",rbuf.mtest);
65 if(strcmp(rbuf.mtest,"quit")==0){
66 break;
67 }
68 }
69 exit(EXIT_SUCCESS);
70 }else{
71 perror("fork error");
72 return -1;
73 }
74
75 return 0;
76 }
msgrcv1:
1 #include <myhead.h>
2 //定义一个消息类型
3 struct msgbuf
4 {
5 long mtype;
6 char mtest[1024];
7 };
8 //宏表示消息正文大小
9 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
10 int main(int argc, const char *argv[])
11 {
12 //1、创建key值
13 key_t key=0;
14 if((key=ftok("/",'k'))==-1){
15 perror("ftok error");
16 return -1;
17 }
18 //根据key值创建一个消息队列
19 int msqid=-1;
20 if((msqid=msgget(key,IPC_CREAT|0664))==-1){
21 perror("msgget error");
22 return -1;
23 }
24 //创建一个子进程
25 pid_t pid=fork();
26
27 if(pid>0){
28 //父进程从消息队列中取出类型为1的消息正文
29 //定义一个消息
30 struct msgbuf rbuf;
31 while(1)
32 {
33 //清空容器
34 bzero(rbuf.mtest,sizeof(rbuf.mtest));
35
36 //从消息队列中读取类型为1的消息正文
37 msgrcv(msqid,&rbuf,MSGSIZE,1,0);
38
39 printf("收到的消息为:%s\n",rbuf.mtest);
40 if(strcmp(rbuf.mtest,"quit")==0){
41 break;
42 }
43 }
44 wait(NULL);
45 }else if(pid==0){
46 //子进程向消息队列中写入类型为2的消息正文
47 //定义一个消息
48 struct msgbuf sbuf;
49 sbuf.mtype=2;
50 while(1)
51 {
52 //清空容器
53 bzero(sbuf.mtest,sizeof(sbuf.mtest));
54
55 printf("发送的消息:");
56 fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
57 sbuf.mtest[strlen(sbuf.mtest)-1]='\0';
58
59 //将消息存放到消息队列
60 msgsnd(msqid,&sbuf,MSGSIZE,0);
61 printf("发送成功\n");
62
63 if(strcmp(sbuf.mtest,"quit")==0){
64 break;
65 }
66 }
67 exit(EXIT_SUCCESS);
68 }else{
69 perror("fork error");
70 return -1;
71 }
72
73 return 0;
74 }
运行结果: