In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/02 Report--
Message queue
Last time we talked about the pipeline of inter-process communication, but the disadvantage of anonymous pipeline is that it can only achieve related inter-process communication, so today we will learn a new way of inter-process communication-message queue.
Message queuing provides a way to send a piece of data from one process to another. Each block is considered to have a type, and the blocks received by the receiver process can have different type values.
Message queues also have the same deficiency as pipes, that is, the maximum length of each data block has an upper limit, and the maximum total length of all queues on the system also has an upper limit.
Message queue function
Header file
# include
< sys/types.h># include
< sys/ipc.h># include
< sys/msg.h>Msgget
Int msgget (key_t key, int msgflg)
Purpose: create and access a message queue
Key: the name of a message queue (similar to each process has a process ID)
Msgflg: it is composed of 9 permission flags. They are used in the same way as the mode flag used when creating files (for example, when a message queue where key already exists, use IPC_CREAT | IPC_EXCL, which is similar to the opening of a file operation: O_CREAT | O_EXCL).
Return value: success will return a non-negative integer, that is, the identification code of the message queue; failure will return-1
Msgsndint msgsnd (int msqid, const void * msgp, size_t msgsz, int msgflg)
Function: add a message to the message queue
Msgid: the message queue identification code returned by the msgget function
Msgp: is a pointer to the message to be sent
The length of the message pointed to by msgsz:msgp, which cannot save the "long int" type in the message type (as we'll see below)
Msgflg: controls what happens when the current message queue is full or reaches the upper limit of the system.
Return value: success-0, failure-1
1)
Struct msgbuf {long mtype; / * message type, must be > 0 * / char mtext [1]; / * message data * /}
The pointer to a message refers to a message to such a structure, which needs to be defined by ourselves. However, the first one must be long int, which indicates the type of message. The type of message is an integer greater than 0 (of course, it can also be equal to 0, but this means that I receive any message, not always one type of message).
Msgtype=0 returns the first message in the queue msgtype > 0 returns the first message msgtype of type equal to msgtype in the queue
< 0返回队列第一条类型小于等于msgtype绝对值的消息msgrcv 作用:从一个消息队列里检索消息 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); msgid:由msgget函数返回的消息队列标识码 msgp:是一个指针,指向准备接收的消息 msgsz:msgp指向的消息长度,这个长度不能保存消息类型里的"long int"类型(下面会说) msgflg:控制着队列中没有相应类型的消息可供接收的时候将要发生的事 msgtyp:可以实现接收优先级的简单形式 返回值:成功-返回实际放到接收缓冲区里的字符个数,失败- "-1" msgflg有以下几个值:Msgflg=IPC_NOWAIT, the queue does not have readable messages and does not wait, and an ENOMSG error is returned. Msgflg=MSG_NOERROR, when the message size exceeds msgsz, msgtype > 0 and msgflg=MSC_EXCEPT are truncated, and the first message whose type is not equal to msgtype is received. Msgctlint msgctl (int msqid, int cmd, struct msqid_ds * buf)
Function: control function of message queue
Msgid: the message queue identification code returned by the msgget function
Cmd: actions to be taken, briefly describe the three commonly used available values:
The msgid_ds data structure is defined as follows:
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 (non-standard) * / 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) * /}; exercise
Try to write a paragraph.
Sender: msgsnd.c
Struct msg_t {long mtype; / / the first must be long, > = 1 char acMsg [20];}; / with ipcs int main () {int msgid; struct msg_t msg = {0}; / / creation, opening and deletion of message queues msgid = msgget (1000 IPC queue creat); if (msgid = =-1) {perror ("create msg");} printf ("msgid =% d\ n", msgid) Msg.mtype = 1; strcpy (msg.acMsg, "hello"); msgsnd (msgid,&msg,sizeof (struct msg_t)-sizeof (long), 0); / / msgctl (msgid,IPC_RMID,NULL); / / you can also use the command ipcrm return 0;}
Receiver: msgrcv.c
Struct msg_t {long mtype; / / the first must be long, > = 1 char acMsg [20];}; int main () {int msgid; struct msg_t msg = {0}; / / creation, opening and deletion of message queues msgid = msgget (1000 msgid 0); if (msgid =-1) {perror ("open msg!\ n");} printf ("msgid =% d\ n", msgid) Msgrcv (msgid,&msg,sizeof (struct msg_t)-sizeof (long), 1J0); printf ("recv msg:% s.\ n", msg.acMsg); return 0;}
Run:
Open three terminals, one running msgsnd.c, one running msgrcv.c, and one to check the status of the message queue:
1. Send first:
2. View: ipcs
3. Read:
4. Check again (taken away):
However, it is also noted that with message queuing, once the message is read, it is gone.
Instant messaging Mini Program
Use message queuing and shared memory (which will be reviewed later) to complete a simple terminal chat program, as follows.
1. The program has a server server, which has an online list. When the terminal logs in, the process ID of the terminal is added to the online list as the user name. (message queuing and shared memory)
two。 When the terminal logs in, it gets the online list of users. (message queues, signals, and shared memory)
3. After logging in the terminal, enter the chat state. : (signal, shared memory)
Enter # chat [pid] to enter private chat mode
For example: # chat 1234, enter into a private chat with terminal 1234. Only the terminal 1234 can receive the message.
Enter # chat 0 to enter group chat mode. All terminals can receive messages.
Description: 1Jing 2jue 3 is the basic function, which is required to be realized. 4, 5, 5, 6 is an additional function, students with ability can try to achieve.
4. When the terminal logs in, the server sends a message to notify other online terminals and update the online list. (signal)
5. The terminal is in chat state. Enter # user to list the online users.
6. The terminal is in the chat state, enter # exit, the terminal exits, and the server removes the process ID of the terminal from the online list, and notifies the online terminal to update the online list. (message queuing and shared memory)
After learning message queuing, you can at least complete the login and logout of the user.
The code is as follows:
Public.h
# ifndef _ PUBLIC_H_#define _ PUBLIC_H_#include
< stdio.h># include
< string.h># include
< sys/types.h># include
< sys/ipc.h># include
< sys/msg.h>Typedef struct login_t {long type; pid_t pid;} LOGIN_T;#define MSG_KEY 1#define MSG_SIZE sizeof (LOGIN_T)-sizeof (long) # endif
Server.c
# include "public.h" int main () {int msg_id; LOGIN_T login = {0}; / create a user's message queue msg_id = msgget (MSG_KEY,0); if (msg_id = =-1) {msg_id = msgget (MSG_KEY,IPC_CREAT); if (msg_id = =-1) {perror ("server msgget") Return-1;}} / / has been listening to whether there are users online while (1) {memset (& login,0,sizeof (LOGIN_T)); msgrcv (msg_id,&login,MSG_SIZE,0,0) / / receive switch (login.type) {case 1: printf ("client% d is logining...\ n", login.pid); break; case 2: printf ("client% d is exiting...\ n", login.pid); break;}} return 0;}
Client.c
# include "public.h" int main () {char acBuf [20] = "; int msg_id; LOGIN_T login = {0}; / / Open message queue msg_id = msgget (MSG_KEY,0); if (msg_id = =-1) {perror (" client msgget "); return-1;} / / Log in, write message queue login.type = 1 / / set the message type of login to 1 login.pid = getpid (); printf ("% d is logining...\ n", login.pid); msgsnd (msg_id,&login,MSG_SIZE,0); / / waiting to write while (1) {putchar ('#'); fflush (stdout); scanf ("% s", acBuf) If (strcmp (acBuf, "quit") = = 0) {login.type = 2; / / sets the message type of exit to 2 msgsnd (msg_id,&login,MSG_SIZE,0); break;}} return 0;}
Run: run the server first, and then run multiple clients
Client:
Server:
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.