在APUE 14.7節(jié)對(duì)消息隊(duì)列的講解中,最后一段說(shuō)“我們得出的結(jié)論是:在新的應(yīng)用程式中不應(yīng)當(dāng)再使用他們。”
 
    雖然在新的應(yīng)用程式中不應(yīng)該再使用消息隊(duì)列,我也沒(méi)有怎么使用過(guò)System V IPC總覺(jué)得在UNIX/Linux編程中少了什么,也許學(xué)習(xí)一下System V IPC對(duì)我的自信心會(huì)有相當(dāng)大的幫助,從此我也敢講我知道如何使用IPC了。

先把各個(gè)函數(shù)原形列出。
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
 
    int msgget(key_t key, int msgflag);
    int msgsnd(int msgid, struct msgbuf *msgp, size_t msgsz, int msgflag);
    ssize_t msgrcv(int msgid, struct msgbuf *msgp, size_t msgsz, long msgtype, int msgflag);
    int msgctl(int msgid, int cmd, struct msqid_ds *buf);
 
    msgget()用來(lái)創(chuàng)建Message Queue(服務(wù)端)或和一個(gè)已建立的Message Queue連接(客戶端)。key,指定用來(lái)生成message id的關(guān)鍵字,msgflag和open()的flags很相似,可用IPC_CREAT, IPC_EXECL, S_IRUSR等。
 
    在服務(wù)端,可用IPC_PRIVATE(或0)來(lái)指定key值,來(lái)生成一個(gè)新的Message Queue,或使用指定的key值(32位的無(wú)符號(hào)數(shù)),或使用ftok()來(lái)生成一個(gè)key。
    #include <sys/types.h>
    #include <sys/ipc.h>
    key_t ftok(const char *pathname, int proj_id);
 
    在客戶端,能夠直接使用服務(wù)端生成的message id(通過(guò)某些途徑傳送,如文檔,父子進(jìn)程),也能夠用msgget通過(guò)和服務(wù)端使用相同的key值來(lái)生成相同的message id,但不能使用IPC_PRIVATE(或0),msgflag也不能使用IPC_CREAT。

    Return Value: Sucess return value is the message id(non-negative integer), otherwise -1 return.
 
    msgsnd()用來(lái)發(fā)送消息。
    struct msgbuf {
            long mtype;
            char mtext[1];
    };
    msgsz的計(jì)算方法: msgsz = sizeof(msgbuf) - sizeof(long);
    msgflag有一個(gè)標(biāo)志:IPC_NOWAIT。當(dāng)消息隊(duì)列已滿(可能是消息總數(shù)達(dá)到了限制值,也可能是隊(duì)列中字節(jié)總數(shù)達(dá)到了限制值),立即出錯(cuò)返回,假如沒(méi)有指定,則阻塞。

    msgrcv()用來(lái)接收消息。msgtype用來(lái)指定讀取的消息類型。msgtype == 0, 返回第一個(gè)消息; msgtype > 0, 返回消息類型為msgtype的消息;msgtype < 0, 返回隊(duì)列中類型值小于msgtype的絕對(duì)值的消息集中最小的消息。
    msgflag有兩個(gè)值:MSG_NOERROR, IPC_NOWAIT。當(dāng)MSG_NOERROR被指定的時(shí)候,若消息太長(zhǎng)就被截?cái)啵駝t返回錯(cuò)誤;IPC_NOWAIT用于需要讀取的消息不存在時(shí)則阻塞。

    msgctl用于控制消息隊(duì)列。cmd有三種值:IPC_STAT,IPC_SET,IPC_RMID。
    IPC_STAT用于取出消息隊(duì)列的 msqid_ds結(jié)構(gòu)并保存到buf中。
    IPC_SET用來(lái)把buf指向的msqid_ds,配置成消息隊(duì)列的msqid_ds。只有四個(gè)值能夠更改:msg_perm.uid, msg_perm.gid,msg_perm.mode, msg_qbytes。
    IPC_RMID用來(lái)刪除消息隊(duì)列。
 
    struct msqid_ds
    {
        struct ipc_perm msg_perm;
        ulong msg_qbytes; //max of bytes of queue
        ...
    };
    struct ipc_perm
    {
        uid_t uid; //owner's effective user id
        gid_t gid; //owner's effective group id
        uid_t cuid; //creator's effective user id
        gid_t cgid; //creator's effective group id
        mode_t mode; //access modes
        ulong seq; //slot usage sequence number
        key_t key;
    };