1. 程式人生 > >自測之Lesson11:消息和消息隊列

自測之Lesson11:消息和消息隊列

nbsp 自測 讀取 set form msgrcv 編寫 recv string

題目:key及ftok函數的作用。

解答:

key是用來創建消息隊列的一個參數,當兩個key相同時,創建消息隊列會引起“誤會”(除非有意為之)。所以我們可以通過ftok函數來獲得一個“不易重復”的key。

key對於進程間通信也有幫助,當一進程知曉另一進程創建消息隊列所用的key後,便可以使用該key訪問該消息隊列。

題目:編寫一個可以向消息隊列發送消息和接收消息的程序。

實現代碼:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {                         // msgbuf結構體
        long mtype;
        char mtext[1024];    
};


void TestMsgSend(int msqid)
{
        while(1) {
                long msgType;
                struct msgbuf msg;
                fprintf(stderr, "Send[FORMAT:type msg]:");
                scanf("%ld%s", &msgType, msg.mtext);
                msg.mtype = msgType;
                int iRet = msgsnd(msqid, &msg, strlen(msg.mtext), 0); 
                if (iRet == -1) {
                        perror("fail msgsnd");
                        return;
                }    
        }
}

void TestMsgRecv(int msqid)
{
        struct msgbuf msg;
        long msgType;
        while (1) {
                fprintf(stderr, "Recv[FORMAT:type]:");
                scanf("%ld", &msgType);
                memset(msg.mtext, 0, 1024);
                msg.mtype = msgType;
                int iRet = msgrcv(msqid, &msg, 1024, msg.mtype, 0);
                if (iRet < 0) {
                        perror ("fail magrcv");
                        return;
                }
                printf("Recv:%s\n", msg.mtext);
        }

}



int main(int argc, char **argv)
{
        if (argc != 2 ||
                (strcmp(argv[1], "r") && strcmp(argv[1], "s")))
        {
                printf("Usage: %s [ r | s ]\n", argv[0]);
                printf("\t r:receive message queue\n");
                printf("\t s:send message queue\n");
                return 0;
        }
        key_t key;
        key = ftok("test1", 1);                 // 創建key
        if (key == -1) {
                perror("fail ftok");
                return -1;
        }
        int msqid;
        msqid = msgget(key, IPC_CREAT | 0664);  // 創建消息隊列
        if (msqid == -1) {
                perror("fail msgget");
                return -1;
        }

        if (argv[1][0] == ‘s‘) {                // 進程1向消息隊列發送消息
                TestMsgSend(msqid);
        }
        else if (argv[1][0] == ‘r‘) {           // 進程2從消息隊列讀取消息
                TestMsgRecv(msqid);
        }

        return 0;
}

  

自測之Lesson11:消息和消息隊列