SystemV消息隊(duì)列 為了便于進(jìn)程之間通信,我們可以使用管道通信 SystemV也提供了一些函數(shù)來(lái)實(shí)現(xiàn)進(jìn)程的通信.這就是消息隊(duì)列.
#include
#include
#include
int msgget(key_t key,int msgflg);
int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg);
int msgrcv(int msgid,struct msgbuf *msgp,int msgsz,
long msgtype,int msgflg);
int msgctl(Int msgid,int cmd,struct msqid_ds *buf);
struct msgbuf {
long msgtype; /* 消息類型 */
……. /* 其他數(shù)據(jù)類型 */
}
msgget函數(shù)和semget一樣,返回一個(gè)消息隊(duì)列的標(biāo)志.msgctl和semctl是對(duì)消息進(jìn)行控制. msgsnd和msgrcv函數(shù)是用來(lái)進(jìn)行消息通訊的.msgid是接受或者發(fā)送的消息隊(duì)列標(biāo)志. msgp是接受或者發(fā)送的內(nèi)容.msgsz是消息的大小. 結(jié)構(gòu)msgbuf包含的內(nèi)容是至少有一個(gè)為msgtype.其他的成分是用戶定義的.對(duì)于發(fā)送函數(shù)msgflg指出緩沖區(qū)用完時(shí)候的操作.接受函數(shù)指出無(wú)消息時(shí)候的處理.一般為0. 接收函數(shù)msgtype指出接收消息時(shí)候的操作.
如果msgtype=0,接收消息隊(duì)列的第一個(gè)消息.大于0接收隊(duì)列中消息類型等于這個(gè)值的第一個(gè)消息.小于0接收消息隊(duì)列中小于或者等于msgtype絕對(duì)值的所有消息中的最小一個(gè)消息. 我們以一個(gè)實(shí)例來(lái)解釋進(jìn)程通信.下面這個(gè)程序有server和client組成.先運(yùn)行服務(wù)端后運(yùn)行客戶端.
服務(wù)端 server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MSG_FILE “server.c”
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main()
{
struct msgtype msg;
key_t key;
int msgid;
if((key=ftok(MSG_FILE,’a'))==-1)
{
fprintf(stderr,”Creat Key Error:%s\a\n”,strerror(errno));
exit(1);
}
if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1)
{
fprintf(stderr,”Creat Message Error:%s\a\n”,strerror(errno));
exit(1);
}
while(1)
{
msgrcv(msgid,&msg,sizeof(struct msgtype),1,0);
fprintf(stderr,”Server Receive:%s\n”,msg.buffer);
msg.mtype=2;
msgsnd(msgid,&msg,sizeof(struct msgtype),0);
}
exit(0);
}
——————————————————————————–
客戶端(client.c)
#include
#include
#include
#include
#include
#include
#include
#include
#define MSG_FILE “server.c”
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main(int argc,char **argv)
{
struct msgtype msg;
key_t key;
int msgid;
if(argc!=2)
{
fprintf(stderr,”Usage:%s string\n\a”,argv[0]);
exit(1);
}
if((key=ftok(MSG_FILE,’a'))==-1)
{
fprintf(stderr,”Creat Key Error:%s\a\n”,strerror(errno));
exit(1);
}
if((msgid=msgget(key,PERM))==-1)
{
fprintf(stderr,”Creat Message Error:%s\a\n”,strerror(errno));
exit(1);
}
msg.mtype=1;
strncpy(msg.buffer,argv[1],BUFFER);
msgsnd(msgid,&msg,sizeof(struct msgtype),0);
memset(&msg,’\0′,sizeof(struct msgtype));
msgrcv(msgid,&msg,sizeof(struct msgtype),2,0);
fprintf(stderr,”Client receive:%s\n”,msg.buffer);
exit(0);
}
注意服務(wù)端創(chuàng)建的消息隊(duì)列最后沒(méi)有刪除,我們要使用ipcrm命令來(lái)刪除的.