所謂訊息佇列就是指一個訊息鏈表。
int msgget(key_t, int flag):建立和開啟隊列
int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int flag):發送訊息,msgid是訊息佇列的id,msgp是訊息內容所在的緩衝區,msgsz是訊息的大小,msgflg是標誌。
int msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int flag):接受訊息,msgtyp是期望接收的訊息類型。
msgqueue.c檔案內容如下;
#include<sys/types.h>#include<sys/ipc.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<pthread.h> // 增加線程支援#define BUFSZ 512struct message{ long msg_type; char msg_text[BUFSZ];};#define MSG_SIZE sizeof(struct message)char app_exit = 0;void *thread_funtion(void *parg);int main(){ int qid; key_t key; int len; int res; pthread_t a_thread; struct message msg; if((key = ftok(".",'a')) == -1){ // ftok 獲得一個key perror("ftok"); exit(1); } if((qid = msgget(key,IPC_CREAT|0666)) == -1){ // 建立一個訊息佇列 perror("msgget"); exit(1); } printf("opened queue %d\n",qid); puts("Please enter the message to queue:"); if((fgets(msg.msg_text,BUFSZ,stdin)) == NULL){ // 從標準輸入獲得buffer puts("no message"); exit(1); } msg.msg_type = getpid(); len = strlen(msg.msg_text) + sizeof(msg.msg_type); if((msgsnd(qid,&msg,len,0)) < 0){ // 發送訊息 perror("message posted"); exit(1); } /* memset(&msg,0,sizeof(msg)); // 清除記憶體為0 if(msgrcv(qid,&msg,len,0) < 0){ // 接收訊息 perror("message recv"); exit(1); } printf("message is:%s\n",(&msg)->msg_text); if((msgctl(qid,IPC_RMID,NULL))<0){ perror("msgctl"); exit(1); }*/ res = pthread_create(&a_thread,NULL,thread_funtion,(void *)&qid); printf("The msgrcv thread is create sucess!\n");while((app_exit = getchar()) != 'e'){sleep(50);} printf("exit main funtion!\n"); exit(0);}void *thread_funtion(void *parg){ struct message msg; int qid; qid = *((int *)parg); memset(&msg,0,MSG_SIZE); while(app_exit != 'e'){ if(msgrcv(qid,&msg,MSG_SIZE) < 0){ sleep(50); continue; } printf("message is:%s\n",(&msg)->msg_text); if(msgctl(qid,IPC_RMID,NULL) < 0){ perror("msgctl"); } sleep(50); }}
Makefile檔案類型如下;
all:msgqueue# which compilerCC = gcc# Where are include file keptINCLUDE = .# Where to installINSTDIR = /usr/local/bin# Options for developmentCFLAGS = -g -Wall -ansimsgqueue:msgqueue.o$(CC) -D_REENTRANT -o msgqueue msgqueue.o -lpthreadmsgqueue.o:msgqueue.c#$(CC) -I$(INCLUDE) $(CFLAGS) -c msgqueue.c#$(CC) -D_REENTRANT -c msgqueue.c -lpthread$(CC) -c msgqueue.cclean:-rm msgqueue.o msgqueueinstall:msgqueue@if [-d $(INSTDIR) ];\ then \ cp msgqueue $(INSTDIR);\ chmod a+x $(INSTDIR)/msgqueue;\ chmod og-w $(INSTDIR)/msgqueue;\ echo "Install in $(INSTDIR)";\ else \ echo "Sorry,$(INSTDIR) does not exist";\ fi