Linux訊息佇列實踐(2)

來源:互聯網
上載者:User

標籤:linux   ipc   訊息佇列   處理序間通訊   cc++   

訊息佇列函數

#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>  int msgget(key_t key, int msgflg);  int msgctl(int msqid, int cmd, struct msqid_ds *buf);  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);  ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);


msgctl函數

功能:擷取/設定訊息佇列的資訊

原型:

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

參數:

    msqid: 由msgget函數返回的訊息佇列標識碼

    cmd:是將要採取的動作(見下)

 

傳回值:

    成功返回0,失敗返回-1

 

cmd:將要採取的動作(有三個可取值),分別如下:


訊息佇列資料結構

struct msqid_ds{    struct ipc_perm msg_perm;     /* Ownership and permissions */    time_t          msg_stime;    /* Time of last msgsnd(2) */    time_t          msg_rtime;    /* Time of last msgrcv(2) */    time_t          msg_ctime;    /* Time of last change */    unsigned long   __msg_cbytes; /* Current number of bytes in                                                queue (nonstandard) */    msgqnum_t       msg_qnum;     /* Current number of messages                                                in queue */    msglen_t        msg_qbytes;   /* Maximum number of bytes                                                allowed in queue */    pid_t           msg_lspid;    /* PID of last msgsnd(2) */    pid_t           msg_lrpid;    /* PID of last msgrcv(2) */};

 

Ipc_perm資料結構

struct ipc_perm{    key_t          __key;       /* Key supplied to msgget(2) */    uid_t          uid;         /* Effective UID of owner */    gid_t          gid;         /* Effective GID of owner */    uid_t          cuid;        /* Effective UID of creator */    gid_t          cgid;        /* Effective GID of creator */    unsigned short mode;        /* Permissions */    unsigned short __seq;       /* Sequence number */};

//實踐:IPC_STATint main(){    int msgid = msgget(0x1234, 0666);    if (msgid == -1)    {        err_exit("msgget error");    }    struct msqid_ds buf;    if (msgctl(msgid,IPC_STAT,&buf) == -1)    {        err_exit("msgctl error");    }    printf("buf.msg_perm.mode = %o\n",buf.msg_perm.mode);   //%o以八進位列印    cout << "buf.__msg_cbytes = " << buf.__msg_cbytes << endl;    cout << "buf.msg_qbytes = " << buf.msg_qbytes << endl;    cout << "buf.msg_lspid = " << buf.msg_lspid << endl;}

//實踐:IPC_SET,一般需要先擷取,然後再設定int main(){    int msgid = msgget(0x1234, 0666);    if (msgid == -1)    {        err_exit("msgget error");    }    //擷取訊息佇列的屬性    struct msqid_ds buf;    if (msgctl(msgid,IPC_STAT,&buf) == -1)    {        err_exit("msgctl get error");    }    //設定訊息佇列的屬性    buf.msg_perm.mode = 0644;    if (msgctl(msgid,IPC_SET,&buf) == -1)    {        err_exit("msgctl set error");    }    //擷取並列印    if (msgctl(msgid,IPC_STAT,&buf) == -1)    {        err_exit("msgctl get error");    }    printf("buf.msg_perm.mode = %o\n",buf.msg_perm.mode);   //%o以八進位列印}

//實踐:IPC_RMID,刪除訊息佇列/**說明:可以通過在多個視窗上運行幾個該程式,測試出:  訊息佇列並沒有運用”引用計數”的功能!*/int main(){    int msgid = msgget(0x1234, 0666);    if (msgid == -1)    {        err_exit("msgget error");    }    int choice = 0;    cout << "Please input Your choice: 0-delete, other-continue: ";    cin >> choice;    if (!choice)    {        //delete msg        if (msgctl(msgid,IPC_RMID,NULL) == -1)        {            err_exit("msgctl IPC_RMID error");        }        else        {            cout << "msgid = " << msgid << ", IPC_RMID OK!" << endl;        }    }}

訊息的發送和接收

msgsnd函數

功能:把一條訊息添加到訊息佇列中

原型

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

參數

    msgid: 由msgget函數返回的訊息佇列標識碼

    msgp:是一個指標,指標指向準備發送的訊息,

    msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息類型的那個long int長整型

    msgflg:控制著當前訊息佇列滿或到達系統上限時將要發生的事情

 

傳回值:

    成功返回0;失敗返回-1

 

    msgflg=IPC_NOWAIT表示隊列滿不等待,返回EAGAIN錯誤。

 

    訊息結構在兩方面受到制約。首先,它必須小於系統規定的上限值;其次,它必須以一個long int長整數開始,接收者函數將利用這個長整數確定訊息的類型

 

訊息結構參考形式如下:

struct msgbuf{    long mtype;       /* message type, must be > 0 */    char mtext[1];    /* message data */};

//實踐/**發送結構*/struct msgBuf{    long mtype;       /* message type, must be > 0 */    char mtext[1024];    /* message data */};int main(){    int msgid = msgget(0x1234,0666|IPC_CREAT);    if (msgid == -1)    {        err_exit("msgget error");    }    //初始化訊息結構    struct msgBuf myBuffer;    myBuffer.mtype = 1;    strcpy(myBuffer.mtext,"Hello XiaoFang!");    //向訊息佇列發送訊息    if (msgsnd(msgid,&myBuffer,strlen(myBuffer.mtext),IPC_NOWAIT) == -1)    {        err_exit("msgsnd error");    }    return 0;}

msgrcv函數

功能:是從一個訊息佇列接收訊息

原型

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
 

參數

    msgid: 由msgget函數返回的訊息佇列標識碼

    msgp:是一個指標,指標指向準備接收的訊息,

    msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息類型的那個long int長整型

    msgtype:它可以實現接收優先順序的簡單形式

    msgflg:控制著隊列中沒有相應類型的訊息可供接收時將要發生的事

 

傳回值:

    成功->返回實際放到接收緩衝區裡去的位元組數;失敗->返回-1

 

msgtyp

msgtyp=0

返回隊列第一條資訊

msgtyp>0

返回隊列第一條類型等於msgtype的訊息

msgtyp<0

返回隊列第一條類型小於等於msgtype絕對值的訊息,並且是滿足條件的訊息類型最小的訊息

 

 

msgflg

msgflg=IPC_NOWAIT

隊列沒有可讀訊息不等待,返回ENOMSG錯誤。

msgflg=MSG_NOERROR

訊息大小超過msgsz時被截斷 

msgtyp>0且msgflg=MSG_EXCEPT

接收類型不等於msgtype的第一條訊息


//實踐:訊息發送int main(){    int msgid = msgget(0x1234,0666|IPC_CREAT);    if (msgid == -1)    {        err_exit("msgget error");    }    struct msgBuf myBuffer;    for (int i = 0; i < 128; ++i)    {        myBuffer.mtype = i+1;        sprintf(myBuffer.mtext,"Hello, My number is %d",i+1);        if (msgsnd(msgid,&myBuffer,strlen(myBuffer.mtext),IPC_NOWAIT) == -1)        {            err_exit("msgsnd error");        }    }    return 0;}

//實踐:訊息接收:從隊首不斷的取資料int main(){    int msgid = msgget(0x1234,0666);    if (msgid == -1)    {        err_exit("msgget error");    }    //從隊首不斷的取資料,連續取10個    struct msgBuf myBuffer;    for (int i = 0; i < 10; ++i)    {        int recvBytes = 0;        if ((recvBytes = msgrcv(msgid,&myBuffer,sizeof(myBuffer.mtext),0,IPC_NOWAIT)) == -1)        {            err_exit("msgrcv error");        }        else        {            cout << "receive recvBytes = " << recvBytes << endl;            cout << "myBuffer.mtype = " << myBuffer.mtype << endl;            cout << "\t" << myBuffer.mtext << endl;        }    }    cout << "strlen(myBuffer.mtext) = " << strlen(myBuffer.mtext) << endl;    return 0;}


Linux訊息佇列實踐(2)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.