消息队列的基本使用思路和接口介绍
来源:互联网 发布:caffe安装教程ubuntu 编辑:程序博客网 时间:2024/06/05 06:41
#include <stdlib.h>#include <errno.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/types.h>#define MSGLENGTH 256#define MSG 0010/* *消息队列,在不关闭的情况下,只要拿到id就可以读取内容,但是当执行过msgrcv后 * 该队列将被删除 **//*生成key用于创建消息队列*/key_t mk_id(int id){ static char path[128 +1]; static int flag=0; key_t key ; if( flag ) goto _not_first_; sprintf(path,"%s/%s",getenv("HOME"),".bashrc"); flag = 1 ;_not_first_: key = ftok(path,id); return ( key );}/*销毁消息队列*/int Close_msg(int id){ return msgctl(id,IPC_RMID,0);}/*读取消息队列的内容*/int Recv_msg(int id,int p_no){ struct s_msg{ long type; char mtext[256]; } msg; int msg_len=0; while(1) { msg_len=msgrcv(id,&msg,MSGLENGTH,0,IPC_NOWAIT|MSG_NOERROR); /*消息读完了就break*/ if(errno == ENOMSG) break; /*读取消息出错*/ if(msg_len==-1 ) { perror("msgrcv"); return -1; } printf("%d:%s\n",p_no,msg.mtext); } return 0;}int Write_msg(int id){ struct s_msg{ long type; char mtext[256]; } msg; char buff [256]; char file_name [256]; FILE *in_file; int snd_len=0; msg.type=MSG; sprintf(file_name,"%s/%s",getenv("HOME"),"tmp/1.dat"); if((in_file=fopen(file_name,"r"))==NULL) { perror("fopen"); exit(-1); } while(fgets(buff,256,in_file) !=NULL) { memcpy((void *)msg.mtext,buff,MSGLENGTH); /*复制string到消息队列*/ snd_len==msgsnd(id,&msg,MSGLENGTH,IPC_NOWAIT); /*出现EAGAIN好像是队列没释放,等会儿就能放进去了*/ if(-1==snd_len && errno != EAGAIN) { perror("msgsnd"); exit(-1); } memset(msg.mtext,0x00,sizeof(msg.mtext)); } fclose(in_file); return 0;}/*创建消息队列*/int Creat_msg(key_t key){ int id=0; if((id=msgget(key,0666|IPC_CREAT)) == -1) { perror("msgget"); exit(-1); } return id;}main(){ int id=0; int proc_num=2; pid_t pid=0; id=Creat_msg(mk_id(MSG)); printf("msg id %d\n",id); Write_msg(id); /*2个线程同时读取消息队列*/ while(proc_num--) { pid=fork(); if(pid==0) { Recv_msg(id,proc_num); exit(-1); } else if (pid <0) { perror("fork"); exit(-1); } } /*等大家都读取完成后销毁队列*/ wait(NULL); Close_msg(id); exit(0);}