Message Queuing 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: Get/Set Message queue information
Prototype:
int msgctl (int msqid, int cmd, struct msqid_ds *buf);
Parameters:
MSQID: Message Queue identification code returned by the Msgget function
CMD: Is the action that will be taken (see below)
return value:
Successful return 0, failure return-1
CMD: The action to be taken (there are three desirable values), respectively, 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) */< c14/>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, 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 in octal print cout << "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, generally need to get first, then set int main () { int msgid = Msgget (0x1234, 0666); if (MsgId = =-1) { err_exit ("Msgget error"); } Gets the properties of the message queue struct Msqid_ds buf; if (Msgctl (msgid,ipc_stat,&buf) = =-1) { err_exit ("Msgctl get Error"); } Set the properties of Message Queuing buf.msg_perm.mode = 0644; if (Msgctl (msgid,ipc_set,&buf) = =-1) { err_exit ("Msgctl SET error"); } Get 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 Print in Octal}
Practice: ipc_rmid, deleting Message Queuing/** Description: You can test by running several of the programs on multiple windows: Message Queuing does not use the "reference count" function!*/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;} } }
sending and receiving of messages
msgsnd function
Function: Add a message to the message queue
Prototype
int msgsnd (int msqid, const void *MSGP, size_t msgsz, int msgflg);
Parameters
MSGID: Message Queue identification code returned by the Msgget function
MSGP: is a pointer to a message ready to be sent,
MSGSZ: Is the length of the message that the MSGP points to, which does not contain the long int length integer that holds the message type
MSGFLG: Controls what is going to happen when the current message queue is full or the system upper limit is reached
return value:
Successful return 0, failure return-1
Msgflg=ipc_nowait indicates that the queue is full without waiting and returns a Eagain error.
The message structure is constrained in two ways. First, it must be less than the upper limit set by the system ; second, it must start with a long int, and the receiver function will use this long integer to determine the type of the message.
The message structure reference form is as follows:
struct msgbuf{ long mtype; /* Message type, must be > 0 */ char mtext[1]; /* Message data */};
Practice/** Send Structure */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"); } Initializes the message structure of struct msgbuf mybuffer; Mybuffer.mtype = 1; strcpy (Mybuffer.mtext, "Hello xiaofang!"); Send message to Message queue if (msgsnd (Msgid,&mybuffer,strlen (Mybuffer.mtext), ipc_nowait) = =-1) { Err_exit (" MSGSND error "); } return 0;}
MSGRCV function
Function: A message is received from a message queue
Prototype
ssize_t MSGRCV (int msqid, void *msgp, size_t msgsz, long Msgtyp, int msgflg);
Parameters
MSGID: Message Queue identification code returned by the Msgget function
MSGP: is a pointer to a message ready to be received,
MSGSZ: Is the length of the message that the MSGP points to, which does not contain the long int length integer that holds the message type
Msgtype: It can achieve a simple form of receiving priority
MSGFLG: Controls What happens when there are no corresponding types of messages in the queue to receive
return value:
Succeeded-Returns the number of bytes actually put into the receive buffer; failure---1
Msgtyp |
Msgtyp=0 |
Returns the first message of the queue |
Msgtyp>0 |
Returns a message with the first type of the queue equal to Msgtype |
Msgtyp<0 |
Returns a message with the first type of a queue that is less than or equal to the absolute value of Msgtype, and is the smallest message type that satisfies the condition |
Msgflg |
Msgflg=ipc_nowait |
The queue does not have a readable message and does not wait to return a enomsg error. |
Msgflg=msg_noerror |
Truncation when message size exceeds MSGSZ |
Msgtyp>0 and Msgflg=msg_except |
The first message that the receive type is not equal to Msgtype |
Practice: Message sent int main () { int msgid = Msgget (0x1234,0666| Ipc_creat); if (MsgId = =-1) { err_exit ("Msgget error"); } struct MSGBUF mybuffer; for (int i = 0; i < ++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: Message Reception: The data is constantly taken from the head of the team int main () { int msgid = Msgget (0x1234,0666); if (MsgId = =-1) { err_exit ("Msgget error"); } From the team's first continuous data fetching, 10 struct msgbuf mybuffer; for (int i = 0; i < ++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 Message Queuing practices (2)