In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/02 Report--
As mentioned last time, it is easy to log in and log out using message queuing. So, it's time to think about where the user list and chat history of the chat should be stored. On the server, of course, then shared memory is needed.
Shared memory allows two unrelated processes to access the same part of logical memory if you need to transfer data between two running processes, shared memory will be a very efficient solution. Shared memory is a special address range created by IPC for a process, which will appear in the address space of the process. Other processes can "connect" the same shared memory segment to their own address space. All processes can access the shared memory address as if they were assigned by malloc. If a process writes data to this shared memory, the changes will be immediately seen by other processes that have access to the same shared memory.
Shared memory function
The functions involved in shared memory are similar to message queues, as follows
Shmget # include
< sys/ipc.h># include
< sys/shm.h>Int shmget (key_t key, size_t size, int shmflg)
Function: used to create shared memory
Key: the name of the shared memory segment size: the amount of memory to be shared shflg: consists of 9 permission flags, which are used in the same way as the mode mode flags used when creating files. The return value is the same: success-returns a non-negative integer, that is, the identification code of the shared memory segment. Failure-returns'- 1'shmatvoid * shmat (int shmid, const void * shmaddr, int shmflg).
Role: shared memory has just been created, no process can access it, in order to establish access to this shared memory segment, we must connect it to the address space of a process, the shmat function is used to complete this work.
The shared memory identity shmaddr returned by shmid:shmget: the address where the shared memory is going to be placed when connecting to the current process shmflg:shmflg is a set of bitwise OR (or) flags. Its two possible values are SHM_RND and SHM_RDONLY return values: success-returns a pointer to the first byte of shared memory; failure-returns'- 1'
Shmaddr is 0, and the core automatically selects an address.
If shmaddr is not 0 and shmflg has no SHM_RND tag, then shmaddr is used as the connection address.
If shmaddr is not 0 and shmflg has the SHM_RND flag set, the connected address is automatically adjusted down to an integral multiple of SHMLBA. Formula: shmaddr-(shmaddr% SHMLBA)
Shmflg=SHM_RDONLY, indicating that the connection operation is used to read-only shared memory
After fork (), the child process inherits the connected shared memory shmdtint shmdt (const void * shmaddr)
Function: detach shared memory from the current process
Shmaddr: the address pointer returned by shmat succeeded-returned '0sink; failed-returned "- 1" leaving shared memory does not mean deleting it, but the current process can no longer access it shmctlint shmctl (int shmid, int cmd, struct shmid_ds * buf)
Function: control function of shared memory
Shmid: shared memory identification code returned by shmget cmd: action to be taken buf: points to a data structure that holds the mode state and access permissions of shared memory
Return value: success-'0mm; failure -'-1'
The actions that cmd will take have the following three values:
That is,
Practice
Write a piece of test code to practice:
Shmwrite.c
# include
< stdio.h># include
< sys/msg.h># include
< sys/ipc.h># include
< sys/types.h>Int main () {int shmid;char * addr;// first detects whether the shared memory of the key exists. If it does, delete the original, and rebuild shmid = shmget (1000 shmid! =-1) {/ / already exists, delete shmctl (shmid,IPC_RMID,NULL);} shmid = shmget (1000 Magazine 1024 shmget creat); if (shmid = =-1) {perror ("error") } / / printf ("shmid:% d\ n", shmid); / / address mapping addr = (char*) shmat (shmid,NULL,0); strcpy (addr, "hello world!"); return 0;}
Shmread.c
# include
< stdio.h># include
< sys/msg.h># include
< sys/ipc.h># include
< sys/types.h>Int main () {int shmid;char * addr = NULL;// first detects whether the shared memory of the key exists. If it does, delete the original and rebuild shmid = shmget (1000 perror 0); if (shmid =-1) {perror ("error");} printf ("shmit:% d\ n", shmid); addr = (char*) shmat (shmid,NULL,0); printf ("% s\ n", addr); / / Unmap shmdt (& addr); return 0;}
Run:
View ipc status:
Instant messaging Mini Program
Next, we can continue with our Mini Program. When there are users online, each client needs to update the online user list, that is, after the server receives the user login message, it needs to send a message (signal,kill) to each online user, and the client prints the user list in the rewrite message processing function.
Then, the status information of the logged-in user should be placed in shared memory so that both the server and client can access it. The shared memory is designed as follows:
Assuming that the maximum number of connected users is 100, a space can be opened up. The first 100 units store the status of each user, and the last 100 units store the corresponding user information. Every time a new user logs in, the server looks for a free block (marked 0) in shared memory, such as finding the location of userAddr+3, setting the flag to 1, moving the pUser pointer to user3, and inserting user information. By the same token, when the user exits, you need to set the flag to 0. At the same time, send a signal to inform the client to read the contents of the shared memory, so that the client can update the user list in a timely manner. (because you need to traverse the id of all users when sending a signal, you can use containers to store user information.)
Based on the last time, the specific code is as follows:
Public.h:
# ifndef _ PUBLICH
# define _ PUBLICH
# include
< stdio.h># include
< string.h># include
< sys/types.h># include
< sys/ipc.h># include
< sys/msg.h># include
< sys/shm.h># include
< signal.h># include
< string># include
< map># include
< iostream>Using namespace std;// user information structure typedef struct user_t {pid_t pid; char uname [10]; / / followed by user name identity, password authentication} USER_T;// login message structure typedef struct login_msg_t {long type; USER_T user;} LMSG_T / / message queue: user login # define LOGIN_TYPE 1#define EXIT_TYPE 2#define MSG_KEY 1000#define MSG_SIZE sizeof (LMSG_T)-sizeof (long) / / shared memory: user list (free block: 0-idle 1-occupied) # define SHM_USER_KEY 1001#define MAX_USER 100#define SHM_USER_SIZE MAX_USER + MAX_USER * sizeof (USER_T) # define SIGNAL_USERS 34#endif
Server.cpp:
# include "public.h"
Int main ()
{
Int msg_id
Int shm_id
LMSG_T loginMsg = {0}
Char userAddr
USER_T pUser; / / the address actually written by the user
Map userMap; / / user list
Map::iterator it
Int i
/ * 1. Create message queue: user login * / 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;}} / * 2, create shared memory: user list * / shm_id = shmget (SHM_USER_KEY,0,0) If (shm_id! =-1) {/ / already exists, delete shmctl (shm_id,IPC_RMID,NULL);} shm_id = shmget (SHM_USER_KEY,SHM_USER_SIZE,IPC_CREAT); userAddr = (char *) shmat (shm_id,NULL,0); / / Mapping pUser = (USER_T *) (userAddr + MAX_USER); memset (userAddr,0,SHM_USER_SIZE) / / initialize / / listen all the time to see if there are users online while (1) {memset (& loginMsg,0,sizeof (LMSG_T)); msgrcv (msg_id,&loginMsg,MSG_SIZE,0,0); / / receive switch (loginMsg.type) {case LOGIN_TYPE: / / log in to cout for any message
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.