UNIX system message queue mechanism and application

xiaoxiao2021-03-06  14

Message queue introduction

In a conventional single task operating system, the program design is running, the program will exclude the entire host resource, and the different modules between the program entities are fully via the global variables, the function calls, the parameter return value when the function is called.

The UNIX operating system is a multi-task operating system, and the program will become a separate entity-process, and communication between the processes includes not only their internal communications, but also communications between processes. A series of process communication organizations in Unix System V, that is, IPC agencies, and message queues are one of them. In UNIX systems, all messages are placed in the system kernel, and they have a corresponding message queue identifier. The process can read and write a specific message in any queue. The second order is the order of the message arrival. The core is responsible for maintaining this appropriate order, and in the same message queue, different processes can read the respective news, in other processes Before writing messages to the message queue, the process can always read the message without waiting for the message to reach the queue.

Every message in the message queue includes the following:

Long integer type

: Define the message type

2. Data length of the message: Define the length of the data

3. Data

: details

The system kernel is a message queue to maintain the following data structure information, which is included in the header file:

Struct msqid_ds {

Struct IPC_Perm MSG_Perms; / * Operation Permission Struct * /

Struct msg * msg_first;

/ * ptr to first message on q * /

Struct msg * msg_last;

/ * ptr to last message on q * /

Ushort

MSG_cBytes;

/ * Current Num Bytes on Q * /

Ushort

MSG_QNUM;

/*o.message on q * /

Ushort

Msg_qbuyes;

/ * max no.bytes for q * /

Ushort

MSG_LspID;

/ * PID of last megsnd * /

Ushort

MSG_LRPID;

/ * pid of last msgrcv * /

Time_t

MSG_stime;

/ * Last Msgsnd Time * /

Time_t

Msg_rtime;

/ * Last MSGRCV Time * /

Time_t

MSG_ctime;

/ * Last Change Time * /

Type USHORT and TIME_T related to system implementation, they are defined in header file ; IPC_PERM structure contains the owner and access rights of the corresponding message queue; the structure MSG is used by the kernel to link the message link on a queue For the queue.

Figure 1 is a schematic diagram of a message queue.

System call format and description

System calls on message queues require the following list files:

#include

#include

#include

1.msgget call

This call is used to create a new message queue or access a message queue already existing. The call format is as follows

INT MSG_QID, MSGFLAG;

Key_t key;

MSG_qid = msgget (key, msgflag)

The parameter key is the key value of the logo message queue. The actual data type of the key is determined by the type key_t related to the implementation. If the call is successful, establish a new message queue, or make an existing message queue can be accessed, Return Value MSG_QID contains an identifier of a message queue.

Parameters msgflag are related to two symbol constants, they are defined in , can be used singly or in place or use:

IPC_CREAT: When executing the MSGGET, establish a new queue when the key value is given, and if the message queue already exists, it is not overwritten. When IPC_CREAT is not set, when the new queue exists, the msgget returns the identifier of the queue.

IPC_EXCL: Both the flag and IPC_CTREAT are set, and the msgget will fail when the key bit has a presented message queue. 2. msgsnd call

After the Msgsnd opens a message queue, you can call the MSGSND to send messages to the message queue, and the format is as follows.

INT MSG_QID, Size, Flags, Len;

Struct my_msg {

Long mtype;

Char mtext [maxvalue];

} message;

Len = msgshd (MSG_QID, & Message, Size, Flags);

Msg_qid: The queue sent to the message is obtained by Msgget.

Message: To point to the structure of the message itself, this structure is defined by the user, where the long MTYPE is important, we can use it to classify the message. Each possible value of this domain represents different types of messages. It is through this domain. The process can receive the message you need from the message queue. Its value must be greater than 0, because the type of type 0 is in the system calls MSGRCV Specially referred to a type. The kernel does not explain any explanation for the message content. MTEXT fields are used to store messages, and maxValue can take anything.

Size: Refers to the actual length of the transmitted, and can take the maximum length of the message specified by the system.

Flags: can be set to IPC_NOWAIT, if it is not set to IPC_Nowait, then when the system does not have enough system resources to send a message, the calling process will enter sleep; otherwise, the call is immediately returned, the return value is -1.

3. msgrcv call

This call is used to read a message from the specified message queue, the call format is as follows:

INT MSG_QID, Size, Flags, Len;

Long MSG_TYPE;

Struct my_msg {

Long mtype;

Char mtext [maxvalue];

} Message; Len = MSGRCV (MSG_QID, & Message, Size, MSG_TYPE, FLAGS);

Msg_qid: To read the queue identifier of the message.

LEN: is the actual length of the received.

Message: The message used to store reads.

SIZE: The maximum length of the message can be stored in the structure.

MSG_TYPE: Used to determine the type of received message. It is selected according to the MTYPE field of the message. If this parameter is 0, you will read the first message in the queue; if the parameter is positive, read the first message of the MTYPE domain for this value; if the parameter is Negative, the message read out of the minimum MTYPE value is selected in the message smaller than or equal to the absolute value of the MSG_TYPE.

Flags: Contains control information, which can be set to IPC_NOWAIT and MSG_NoError, or the result of the bit or one of them. If set to ipc_nowait, there is no suitable message in the queue, the call is returned, otherwise it will enter sleep. If set to msg_noerror, the message is truncated when the message length is greater than size, otherwise the call failed.

4. MSGCTL call

This call has three functions, obtain status information of the message queue, changing some restrictions on the message queue, remove a queue from the system, the modulation format is as follows:

INT MSG_QID, Command, Len;

Struct MSQID_DS MSQ_STAT;

MSGCTL (MSG_QID, Command, & MSQ_STAT)

Msg_qid: is a valid message queue identifier.

MSG_STAT: is an address of an MSGID_DS structure.

Command: Indicates the operation to be completed.

There are three options, defined in , their significance is as follows:

· IPC_STAT: Put the status information about the structure in MSG_STAT.

· IPC_SET: Depending on the information in the msg_stst, set the control variable value for the message queue.

· IPC_rmid: Remove the queue from the system, but only superuser or queue owners can use.

Message queue application

The apparatus for a message queue in the C / S mode will be described below. An important feature of C / S is non-equal, multiple clients simultaneously present different requests to a server, and after receiving and handling the client's request, returning the result to the corresponding client. Here, we use two messages, a service process, a number of customer processes to simulate a client / service application. The request information is written to the queue 1 (key value 0x16) by each customer process, and the message type is set; the service process is handled from the message of the type 10 in the queue 1, and the processing result is placed in the message queue 2 (key Value 0x17), set the type as the original customer process number, so that each customer process can read the result from Queue 2 according to the message number of the message number (Fig. 2). Start the service process (Server.c) first, create two message queues, the key values ​​are 16 and 17, respectively; then start a number of customer processes (Client.c), enter an argument, At this time, the service process displays the customer process number and the original string, and the customer process returns the first character being changed to the "_" string and message type (own process number). If you enter the character "Q", remove the original message queue and exit. After the source program is enclosed, the program compiles commissioning in UNIX3.2, 4.2.

This is just the implementation of the process communication within the machine. To implement the communication between the network machine, it is necessary to achieve the socket of the UNIX Internet system.

The source program list is as follows:

Service process: (Server.c)

#include

#include

#include

#include

#define key16 (Key_T) 16

#define key17 (Key_T) 17

#include (ctype.h)

INT I, MSGID1, MSGID2, VAL;

Char * s

Struct {

Long mtype;

Short style;

CHAR MTEXT [40];

} BUF;

Main ()

{

CR_Q (); / * Create a message queue * /

/ * Read Message Queue 1, Message Queue Type 10, waiting for customer request * /

While (MSGRCV (MSGID1, & BUF, 42, (long) 10, ~ ipc_nowait> = 0)

{Printf ("/ N Text from Client IS: [% S]", BUF.MText);

Printf ("Client PID IS <% D> /N", BUF.Stype);

Process (); / * Write the results to the message queue 2 * /

}

}

CR_Q ()

{Msgid1 = msgget (key16, ipc_creat | 0666);

IF (MSGID1 <0) {PERROR ("Key16 Msgget Failed"; exit (1);

MSGID2 = msgget (key17, ipc_creat | 0666);

IF (MSGID2 <0) {PERROR ("Key17 Msgget Failed"; exit (1);}

}

PROCESS ()

{

BUF.MTYPE = BUF.Stype; / * Original customer process number * /

BUF.MTEXT [0] = '_';

IF (Msgid2, & Buf, 42, IPC_NOWAIT <0)

{Perror ("Key17 Msgsnd Failed"); exit (1);}

}

Customer process: (Client.c)

#include

#include

#include

#include

Define Key16 (Key_T) 16Define Key17 (Key_T) 17

INCLUDE

INT MSGID1, MSGID2;

Struct {

Long mtype;

Short style;

CHAR MTEXT [40];

} BUF;

Char s [41];

Int clean ()

Main ()

{

Get_q (); / * Cancel Queue Narrator * /

While (1)

{

Printf ("/ n @ INPUT MTEXT:"); / * Enter string * /

Scanf ("% s", s);

IF ((STRCMP (S, "Q") == 0)) Break;

STRCPY (BUF.MText, s);

BUF.MTYPE = 10; / * Message type is 10 * /

BUF.Stype = getPid (); / * Customer process number * /

/ * Write Message Queu 1, ask the service process * /

IF (msgid1, & buf, 40, ~ ipc_nowait) <0)

{Perror ("Key16 Msgsnd Failed"; exit (1);}

/ * Read Message Queue 2, type is your own process number, receive processing result * /

IF (MSGRCV (MSGID2, & BUF, 42, getPid (), ~ IPC_NOWAIT <0)

{PERROR ("Key17 Msgrcv Failed"; exit (1);

Printf ("/ N the answer from server is: [% s]", buf.mtext);

Printf ("MTYPE IS: [% D]", BUF.MTYPE;

}

Clean (); / * Delete Message Queue * /

}

Clean ()

{

IF (MSGCT1 (MSGID1, IPC_rmid, (struct msgid *) null) <0)

{Perror ("Key16 Msgct1 Failed"; exit (1);}

IF (MSGCT1 (MSGID2, IPC_rmid, (struct msgid *) NULL <0)

{Perror ("key17 msgct1 failed"; exit (1);

Printf ("MSG Queue Removed / N);

exit (0);

}

Get_q ()

{

Msgid1 = msgget (key16 ,0);

IF (MSGID1 <0) {PERROR ("Key16 Msgget Failed"; exit (1);

MSGID2 = msgget (key17, 0);

IF (MSGID2 <0) {PERROR ("Key17 Msgget Failed"; exit (1);}

}

转载请注明原文地址:https://www.9cbs.com/read-49368.html

New Post(0)