標籤:linux ipc 訊息佇列 處理序間通訊 cc++
API綜合使用
//父進程發送訊息,子進程接收訊息struct msgBuf{ long mtype; /* message type, must be > 0 */ char mtext[104]; /* message data */};const int MSGNUMBER = 10;int main(){ //擷取一個鍵 key_t msgKey = ftok("/tmp/mySeedFile",‘f‘); //擷取一個訊息佇列 int msgid = msgget(msgKey,IPC_CREAT|0666); if (msgid == -1) { err_exit("msgget error"); } struct msgBuf myBuffer; pid_t pid = fork(); if (pid == -1) { err_exit("fork error"); } //父進程,發送資料 if (pid > 0) { myBuffer.mtype = getpid(); //向訊息佇列中發送訊息,如果隊列full,則該進程一直阻塞 for (int i = 0; i < MSGNUMBER; ++i) { sprintf(myBuffer.mtext,"Hello, My Number is %d",i); msgsnd(msgid,&myBuffer,strlen(myBuffer.mtext),0); } //等待子進程結束 wait(NULL); } else if (pid == 0) //子進程 { //睡眠1秒,等待父進程發送結束 sleep(1); memset(&myBuffer,0,sizeof(myBuffer)); //從隊首不斷的取資料 for (int i = 0; i < MSGNUMBER; ++i) { int recvBytes = 0; if ((recvBytes = msgrcv(msgid,&myBuffer,sizeof(myBuffer.mtext), getppid(),IPC_NOWAIT)) == -1) { err_exit("msgrcv error"); } else { cout << "recvBytes = " << recvBytes << endl; cout << "myBuffer.mtype = " << myBuffer.mtype << endl; cout << "\t" << myBuffer.mtext << endl; } } cout << "strlen(myBuffer.mtext) = " << strlen(myBuffer.mtext) << endl; } return 0;}
訊息佇列項目開發案例
訊息佇列實現回射客戶/伺服器
/**一個簡化實現->程式說明: 1.用戶端發送資料格式: 類型為:用戶端pid 內容為鍵盤輸入的內容2.用戶端接收格式 類型為自己的pid 內容為伺服器發送過來的內容 3.伺服器接收的資料 類型為用戶端pid 內容為各個用戶端的訊息內容 4.伺服器發送的資料 類型為用戶端id 內容為用戶端訊息內容*/
//server.cpp#include "commen.h"void echo_server(int msgid){ struct msgBuf myMsgBuf; while (true) { memset(&myMsgBuf,0,sizeof(myMsgBuf)); int recvBytes = msgrcv(msgid,&myMsgBuf,MAXMSGSIZE,0,0); if (recvBytes == -1) { err_exit("msgrcv error"); } fputs(myMsgBuf.mtext,stdout); if (msgsnd(msgid,&myMsgBuf,strlen(myMsgBuf.mtext),0) < 0) { err_exit("msgsnd error"); } }}int main(){ key_t key = ftok(FILESEED,‘f‘); int msgid = msgget(key,0666|IPC_CREAT); if (msgid == -1) { err_exit("msgget error"); } echo_server(msgid); return 0;}
//client.cpp#include "commen.h"void echo_client(int msgid){ struct msgBuf myMsgBuf,recvMsgBuf; myMsgBuf.mtype = getpid(); while (fgets(myMsgBuf.mtext,MAXMSGSIZE,stdin) != NULL) { if (msgsnd(msgid,&myMsgBuf,strlen(myMsgBuf.mtext),0) == -1) { err_exit("msgsnd error"); } memset(&recvMsgBuf,0,sizeof(recvMsgBuf)); if (msgrcv(msgid,&recvMsgBuf,sizeof(recvMsgBuf),getpid(),0) == -1) { err_exit("msgrcv error"); } fputs(recvMsgBuf.mtext,stdout); memset(&myMsgBuf+4,0,sizeof(myMsgBuf)-4); }}int main(){ key_t key = ftok(FILESEED,‘f‘); int msgid = msgget(key,0666); if (msgid == -1) { err_exit("msgget error"); } echo_client(msgid); return 0;}
//commen.h#ifndef COMMEN_H_INCLUDED#define COMMEN_H_INCLUDED#include <string>#include <string.h>#include <errno.h>#include <stdlib.h>#include <stdio.h>const char FILESEED[] = "/tmp/mySeedFile";const int MAXMSGSIZE = 1024;struct msgBuf{ long mtype; //Message Type: Client PID char mtext[MAXMSGSIZE]; //message data};void err_exit(std::string str){ perror(str.c_str()); exit(EXIT_FAILURE);}#endif // COMMEN_H_INCLUDED
開拓眼界
附-Makefile
CC = g++ CPPFLAGS = -Wall -gBIN = client server SOURCES = $(BIN.=.cpp).PHONY: clean all all: $(BIN)$(BIN): $(SOURCES)clean: -rm -rf $(BIN) bin/ obj/ core
Linux訊息佇列實踐(3)