消息队列和信号量

来源:互联网 发布:浏览器打开淘宝很慢 编辑:程序博客网 时间:2024/06/06 07:00

程序的实现是两个进程,通过信号量来实现通信,发送方先request发送方的信号量,然后发送,然后再release接收方信号量,这样可以通知接手方可以接收了,接受方接收以后再通过信号量通知发送方,一直这样循环,直到发送方发送"exit"双方才能退出进程。

数据的传送是通过消息队列传送的。

具体对函数的介绍和实现方法这里就不多说了,信号量和消息队列的知识点还是有点多的,可以参考《linux程序设计》这本书,书上讲的很详细,例题也很好!

下面就贴上代码给大家参考参考!

发送代码:

#include <stdio.h>#include <sys/ipc.h>#include <sys/types.h>#include <sys/sem.h>#include <sys/msg.h>#include <unistd.h>#include <stdlib.h>#define SIZE 128struct msgbuf//消息的发送和接受要用到的结构体{long mtype;//消息的类型char mtext[SIZE];//消息的数据};/**功能:发送消息*参数1:信号量的ID*参数2:消息的ID*如果发送“exit”字符串,返回-1,其它返回0;*/int send(int sem_id, int msg_id){struct msgbuf msg;if ( request_sem(sem_id, 0) == -1 )//请求第一个信号量的资源{printf("request the frist semaphore failed!\n");}msg.mtype = 1;printf("input:");fgets(msg.mtext,sizeof(msg.mtext),stdin);msgsnd(msg_id, &msg, SIZE, 0);//发送到消息队列中if ( release_sem(sem_id,1) == -1 )//释放第二个信号量的资源{printf("release the second semaphore failed!\n");}if ( strcmp(msg.mtext,"exit\n") == 0 )return -1;return 0;}void init_sem(int sem_id){semctl(sem_id,0,SETVAL,1);//对第一个信号量的初始化semctl(sem_id,1,SETVAL,0);//对第二个信号量的初始化}int create_sem(key_t key)//创建信号量{return semget(key,2,IPC_CREAT | 0666 );}int create_msg(key_t key)//创建消息队列{return msgget(key,IPC_CREAT | 0666);}int release_sem(int sem_id, int i)//释放信号量函数{struct sembuf sb;sb.sem_num = i;//信号量的索引sb.sem_op = 1;//1表示信号量加1sb.sem_flg = SEM_UNDO;//信号量资源不够时等待资源的释放return semop(sem_id,&sb,1);}int request_sem(int sem_id, int i)//信号量的请求{struct sembuf sb;sb.sem_num = i;sb.sem_op = -1;//-1表示信号量-1sb.sem_flg = SEM_UNDO;return semop(sem_id,&sb,1);}int main(){int sem_id;int msg_id;key_t key;//char buffer[SIZE];key = ftok(".",'e');sem_id = create_sem(key);msg_id = create_msg(key);if (sem_id == -1 || msg_id == -1){printf("create failed\n");exit(0);}init_sem(sem_id);while(1){if ( send(sem_id, msg_id) == -1 )break;}return 0;}

第二段代码就不注释了,大致相同,如果第一段能看懂第二段就没问题了。

接收代码:


#include <stdio.h>#include <sys/ipc.h>#include <sys/types.h>#include <sys/sem.h>#include <sys/msg.h>#include <unistd.h>#include <stdlib.h>#define SIZE 128struct msgbuf{long mtype;char mtext[SIZE];};int recive(int sem_id, int msg_id){struct msgbuf msg;if ( request_sem(sem_id, 1) == -1 ){printf("request the second semaphore failed!\n");}msgrcv(msg_id, &msg, SIZE, 0, 0);printf("%s",msg.mtext);if ( strcmp(msg.mtext,"exit\n") == 0)return -1;if ( release_sem(sem_id,0) == -1 ){printf("release the frist semaphore failed!\n");}return 0;}void init_sem(int sem_id){semctl(sem_id,0,SETVAL,1);semctl(sem_id,1,SETVAL,0);}int create_sem(key_t key){return semget(key,2,IPC_CREAT | 0666 );}int create_msg(key_t key){return msgget(key,IPC_CREAT | 0666);}int release_sem(int sem_id, int i){struct sembuf sb;sb.sem_num = i;sb.sem_op = 1;sb.sem_flg = SEM_UNDO;return semop(sem_id,&sb,1);}int request_sem(int sem_id, int i){struct sembuf sb;sb.sem_num = i;sb.sem_op = -1;sb.sem_flg = SEM_UNDO;return semop(sem_id,&sb,1);}int main(){int sem_id;int msg_id;key_t key;key = ftok(".",'e');sem_id = create_sem(key);msg_id = create_msg(key);if (sem_id == -1 || msg_id == -1){printf("create failed\n");exit(0);}while(1){if ( recive(sem_id, msg_id) == -1)break;}msgctl(msg_id,IPC_RMID,0);return 0;}


原创粉丝点击