Inter-process communication-Message Queue

Source: Internet
Author: User

1. Create a Message Queue

 

# Include <sys/msg. h>

Int msgget (key_t key, int flags );

 

The key in the parameter is used to convert it into an identifier. Flags indicates the behavior of the function.

 

// Creat_msg.c

# Include <sys/msg. h>
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <stdio. h>
# Include <stdlib. h>

Int main ()
{
Int qid;
Key_t key;

Key = 113;
Qid = msgget (Key, ipc_creat | 0666); // create a message queue with a permission of 0666

If (qid <0 ){
Perror ("msgget ");
Exit (1 );
}

Printf ("created queue ID: % d/N", qid );

System ("IPCS-Q"); // view the status of the system IPC

Return 0;
}

 

Result:

./Creat_msg
Created queue ID: 0

------ Message queues --------
Key msqid owner perms used-bytes messages
0x00000071 0 Alei 666 0 0

The msgctl function can perform multiple operations on the queue.

 

# Include <sys/msg. h>

Int msgctl (INT msqid, int cmd, struct msqid_ds * BUF );

 

Return Value: 0. If yes.
-1. If the command fails: errno = eacces (CMD is ipc_stat without the read permission)
Efault (the address that the Buf points to is invalid)
Eidrm (the read queue is deleted)
Einval (msgqid is invalid, or msgsz is smaller than 0)
Eperm (the ipc_set or ipc_rmid command is used, but the caller has no write permission)
Let's take a look at several commands that can be used (namely the CMD parameter ):
Ipc_stat
Read the data structure msqid_ds of the message queue and store it in the address specified by B u F.
Ipc_set
Set the value of the ipc_perm element in msqid_ds. This value is taken from the Buf parameter.
Ipc_rmid
Remove Message Queue from System Kernel

 

// Del_msg.c

# Include <sys/msg. h>
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <stdio. h>
# Include <stdlib. h>

Int main (INT argc, char * argv [])
{
Int qid;

If (argc! = 2 ){
Puts ("Usage: del_msg queue_id ");
Exit (1 );
}

Qid = atoi (argv [1]);
System ("IPCS-Q ");

If (msgctl (qid, ipc_rmid, null) <0) {// delete a specified message queue
Perror ("msgctl ");
Exit (1 );
}

System ("IPCS-Q ");
Printf ("successfully removed % d queue/N", qid );

Return 0;
}

 

 

Result:

Alei @ Alei-desktop :~ /Linux/code/14 $./del_msg
Usage: del_msg queue_id
Alei @ Alei-desktop :~ /Linux/code/14 $./del_msg 0

------ Message queues --------
Key msqid owner perms used-bytes messages
0x00000071 0 Alei 666 0 0

------ Message queues --------
Key msqid owner perms used-bytes messages

Successfully removed 0 queue

 

 

2. read/write message queues

 

Add a message to the queue:

 

# Include <sys/msg. h>

Intmsgsnd (INT msqid, struct msgbuf * msgp, int msgsz, int msgflg );
Returned value: 0 if successful.
If it fails,-1: errno = eagain (the queue is full and ipc_nowait is used)
Eacces (no write permission)
Efault (invalid msgp address)
Eidrm (Message Queue deleted)
Eintr (receives a signal when waiting for write operations)
Einval (Invalid Message Queue identifier, non-positive message type, or
Invalid Message length)
Enomem (There is not enough memory to copy the message buffer)

The first parameter of the System Call msgsnd () is the message queue identifier, Which is returned by the System Call msgget. The second parameter is msgp, which is a pointer to the message buffer. The msgsz parameter contains the size of the message in bytes, but does not include the length of the Message Type (4 bytes ).
The msgflg parameter can be set to 0 (ignore this parameter) or ipc_nowait.

If the message queue is full, the message will not be written to the message queue, and the control will return to the calling process. If not specified, the calling process will be suspended until the message can be written to the queue.

 

PTR points to a msgbuf structure, which is defined as follows:

Struct msgbuf {

Long mtype;

Char mbuf [];

}

The length depends on the specific message, but remember: the message cannot end with null.

 

Msgrcv can be used to read messages from the queue:

# Include <sys/msg. h>

Int msgrcv (INT msqid, struct msgbuf * msgp, int msgsz, long mtype, int msgflg );
Return Value: If successful, the number of bytes copied to the message buffer is returned.
-1: errno = e2big (message length is greater than msgsz, no msg_noerror) is returned if the message fails)
Eacces (no read permission)
Efault (the address that msgp points to is invalid)
Eidrm (the queue has been deleted)
Eintr (interrupted by signal)
Einval (msgqid is invalid, or msgsz is smaller than 0)
Enomsg (ipc_nowait is used, and messages in the queue cannot meet the requirements)
Obviously, the first parameter is used to specify the queue for reading messages. The second parameter represents the address of the message buffer for storing messages. The third parameter is the message buffer length, excluding the mtype length. It can be calculated as follows:
Msgsz = sizeof (structmymsgbuf)-sizeof (long );
The fourth parameter is the type of the message to be read from the message queue. If the value of this parameter is 0, the longest message in the queue will be returned regardless of its type.
If ipc_nowait is used as a flag in the call, when no data is available, the call will return enomsg to the call process. Otherwise, the calling process will be suspended until the queue is in progress.
A message meets the msgrcv () parameter requirements. If the queue is empty when the client waits for a message, eidrm is returned. If a process captures a signal while waiting for a message,
Eintr is returned.

 

 

// Snd_msg.c

# Include <sys/msg. h>

# Include <sys/types. h>

# Include <sys/IPC. h>

# Include <stdio. h>

# Include <stdlib. h>
# Include <string. h>

 
Struct MSG {

Long msg_types;

Char msg_buf [511];

};

 
Int main (void ){

Int qid;

Int PID;

Int Len;

Struct msg pmsg;


PMSG. msg_types = getpid (); // The message type is the ID of the current process.

Sprintf (PMSG. msg_buf, "Hello! This is: % d/n/0 ", getpid (); // initialize the message

Len = strlen (PMSG. msg_buf); // or sizeof (struct MSG)-sizeof (long)


If (qid = msgget (ipc_private, ipc_creat | 0666) <0) {// create a message queue

Perror ("msgget ");

Exit (1 );

}


If (msgsnd (qid, & PMSG, Len, 0) <0) {// you want to send a message in the Message Queue

Perror ("msgsn ");

Exit (1 );

}

 
Printf ("successfully send a message to the queue: % d/N", qid );

Exit (0 );

}

 

 

// Rcv_msg.c

# Include <sys/msg. h>

# Include <sys/types. h>

# Include <sys/IPC. h>

# Include <stdio. h>

# Include <stdlib. h>

 
# Define bufsz 4096

 
Struct MSG {

Long msg_types;

Char msg_buf [511];

};

 
Int main (INT argc, char * argv []) {

Int qid;

Int Len;

Struct msg pmsg;

 
If (argc! = 2 ){

Perror ("Usage: read_msg <queue ID> ");

Exit (1 );

}


Qid = atoi (argv [1]);

 
Len = msgrcv (qid, & PMSG, bufsz, 0, 0 );


If (LEN> 0 ){

PMSG. msg_buf [Len] = '/0'; // Add an end character for the message

Printf ("reading queue ID: % 05ld/N", qid); // output queue ID

Printf ("Message Type: % 05ld/N", PMSG. msg_types );

Printf ("message length: % d Bytes/N", Len );

Printf ("mesage text: % s/n", PMSG. msg_buf );

}

Else if (LEN = 0)

Printf ("have no message from queue % d/N", qid );

Else {

Perror ("msgrcv ");

Exit (1 );

}

System ("IPCS-Q ");
Return 0;

}

 

Result:

Alei @ Alei-desktop :~ /Linux/code/14 $./snd_msg
Successfully send a message to the queue: 98304
Alei @ Alei-desktop :~ /Linux/code/14 $./rcv_msg 98304
Reading queue ID: 98304
Message Type: 05788
Message length: 20 bytes
Mesage text: Hello! This is: 5788

------ Message queues --------
Key msqid owner perms used-bytes messages
0x00000000 98304 Alei 666 0 0

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.