Linux Message Queue practice (2) and linux Message Queue practice
Message Queue Functions
#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 Function
Function: gets/sets Message Queue information.
Prototype:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
Parameters:
Msqid: ID of the Message Queue returned by the msgget Function
Cmd: the action to be taken (see below)
Return Value:
0 is returned for success and-1 is returned for failure.
Cmd: the action to be taken (three values are available), which are as follows:
Message Queue Data Structure
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 Data Structure
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 */};
// Practice: IPC_STATint main () {int msgid = msgget (0x1234,066 6); 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 prints cout in octal format <"buf. _ msg_cbytes = "<buf. _ msg_cbytes <endl; cout <"buf. msg_qbytes = "<buf. msg_qbytes <endl; cout <"buf. msg_lspid = "<buf. msg_lspid <endl ;}
// Practice: IPC_SET, which is usually obtained first, and then set int main () {int msgid = msgget (0x1234,066 6); if (msgid =-1) {err_exit ("msgget error");} // obtain the Message Queue attribute struct msqid_ds buf; if (msgctl (msgid, IPC_STAT, & buf) =-1) {err_exit ("msgctl get error");} // sets the Message Queue attribute buf. msg_perm.mode = 0644; if (msgctl (msgid, IPC_SET, & buf) =-1) {err_exit ("msgctl set error ");} // obtain and print if (msgctl (msgid, IPC_STAT, & buf) =-1) {err_exit ("msgctl get error");} printf ("buf. msg_perm.mode = % o \ n ", buf. msg_perm.mode); // % o printed in octal format}
// Practice: IPC_RMID, delete message queue/** Note: You can run several programs in multiple windows to test the following code: message Queue does not use the reference count function! */Int main () {int msgid = msgget (0x1234,066 6); 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 ;}}}
Message sending and receiving
Msgsnd Function
Function: adds a message to the message queue.
Prototype
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
Parameters
Msgid: ID of the Message Queue returned by the msgget Function
Msgp: A pointer pointing to the message to be sent,
Msgsz: refers to the message length pointed to by msgp. This length does not include the long int that saves the message type.
Msgflg: controls what will happen when the current message queue is full or when it reaches the system
Return Value:
0 is returned for success;-1 is returned for failure.
Msgflg = IPC_NOWAIT indicates that the queue is full and does not wait, and an EAGAIN error is returned.
The message structure is restricted in two aspects. First, it must be smaller than the upper limit specified by the system. Second, it must start with a long int, and the receiver function will use this long integer to determine the message type.
The message structure Reference is as follows:
struct msgbuf{ long mtype; /* message type, must be > 0 */ char mtext[1]; /* message data */};
// Practice/** sending structure */struct msgBuf {long mtype;/* message type, must be> 0 */char mtext [1024]; /* message data */}; int main () {int msgid = msgget (0x1234,066 6 | IPC_CREAT); if (msgid =-1) {err_exit ("msgget error");} // initialize the message structure struct msgBuf myBuffer; myBuffer. mtype = 1; strcpy (myBuffer. mtext, "Hello XiaoFang! "); // Send the message if (msgsnd (msgid, & myBuffer, strlen (myBuffer. mtext), IPC_NOWAIT) =-1) {err_exit ("msgsnd error") ;}return 0 ;}
Msgrcv Function
Function: receives messages from a message queue.
Prototype
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
Parameters
Msgid: ID of the Message Queue returned by the msgget Function
Msgp: A pointer pointing to the message to be received,
Msgsz: refers to the message length pointed to by msgp. This length does not include the long int that saves the message type.
Msgtype: a simple form of receiving priority.
Msgflg: controls what will happen when there are no corresponding types of messages in the queue for receiving.
Return Value:
Success-> return the number of bytes actually placed in the receiving buffer; fail-> return-1
Msgtyp |
Msgtyp = 0 |
Returns the first message of the queue. |
Msgtyp> 0 |
Returns the message whose first type is msgtype. |
Msgtyp <0 |
Return the first message in the queue whose type is smaller than or equal to the absolute value of msgtype and is the minimum message type that meets the conditions. |
Msgflg |
Msgflg = IPC_NOWAIT |
If the queue does not have readable messages and does not wait, an ENOMSG error is returned. |
Msgflg = MSG_NOERROR |
The message is truncated when the message size exceeds msgsz. |
Msgtyp> 0 and msgflg = msg_0000t |
The receiving type is not equal to the first message of msgtype. |
// Practice: Message sending int main () {int msgid = msgget (0x1234,066 6 | 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 ;}
// Practice: receive a message: continuously retrieve data from the beginning of the queue int main () {int msgid = msgget (0x1234,0666); if (msgid =-1) {err_exit ("msgget error");} // continuously retrieves data from the beginning of the team, and obtains 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 ;}