Cross-platform (Linux) development based on VS2019 C++ (1.5) - shared memory

I. Introduction

        In the previous pipeline learning, we used named pipes to generate two .fifo files. If users do not understand technology, they may delete them if they think this file is useless. In addition, because the maximum data that a pipe (whether it is a named pipe or an anonymous pipe) can hold is limited (65535 bytes), you keep writing data to the pipe, and if you exceed this capacity, the pipe may be damaged. (Just like the amount of water that a water pipe can carry is limited, and it may burst if it exceeds a certain water pressure), so in summary, the pipe is easy to be deleted by mistake, and the capacity of the pipe has an upper limit. Then the next step involves shared memory.

2. Overview of Shared Memory

        Shared memory is a special address range created by IPC for a process that will appear in the process' address space. Other processes can "link" the same shared memory segment into their own address space. As shown below

① The shared memory in the above figure may be created by one of the processes of A or B. But it does not belong to any process (not to A nor to B), it belongs to the operating system itself.

② Both A and B processes can access the shared memory address as if they were allocated by malloc.

③ If process A writes data to this shared memory, the changes will be immediately seen by other processes that have access to the same shared memory, such as process B here.

        It can be imagined as a shared bicycle and shared charging treasure in reality. First, neither of these belong to the user; second, everyone has the right to use it; finally, if the previous user broke it, and the second user happened to use it, then its state was broken last time condition. To be more specific, if the shared power bank used by the previous user uses 30% of the power, then if the latter user uses it immediately, only 70% of the power is available for use. Of course, it is assumed that When the power bank has not been charged

        So to put it simply, sharing has the following three characteristics: this thing does not belong to you; anyone can use it; the latter person will definitely be able to see the operation results of the former person.

        Back to the concept of shared memory, that is, this memory does not belong to any process; all processes can use this memory; if a process changes the memory, other processes can see the result of the operation.

You can view shared memory, message queues, and semaphores through the ipcs command. Signals and pipes belong to a certain process space, but these three belong to the operating system itself, and it does not matter whether the process exists or not. That is, these three things are independent of the process. If the process is not open, the shared memory can still exist (as shown in the figure below).

ipcrm -m shmid delete the shared memory of the specified id

ipcm -a deletes all created shared memory, semaphores, etc. (except root)

 3. Shared memory function

1. shmget function - create

Role: used to create shared memory

原型:int  shmget(key_t key,size_t size, int shmflg);

Parameter Description:

  • key: the name of the shared memory segment
  • size: shared memory size
  • shmflg: consists of nine permission flags (read, write, execute - 0777), the usage is the same as the mode flag used when creating the file, but umask(0) is not required

Return value: If the shared memory is created successfully, it returns a non-negative integer, that is, the identification code (shm_id) of the shared memory; if it fails, it returns "-1" 

Note : This function has two meanings: if it does not exist, create it; if it exists (judged by the key), it does not operate

2, shmat function - connection

Function: When the shared memory segment is just created, no process can access it yet. In order to establish an access channel to this shared memory segment, we must connect it to the address space of our own process (like sharing a bicycle you To use after scanning the code to pay)

原型:void* shmat(int shm_id,     const void *shm_addr,     int shmflg);

Parameter Description:

  • shm_id: shared memory ID returned by shmget
  • shm_addr: The address where the shared memory is to be placed when it is connected to the current process
  • shmflg is a set of flags that are bitwise ORed together. Its two possible values ​​are SHM_RND and SHM_RDONLY

Return value: If the call succeeds, it returns a pointer, which points to the first byte of the shared memory; if it fails, it returns "-1" (void* means that any type can be stored , because it just connects and doesn't know what type it is. )

3, shmdt function - disconnect

Function: separate the shared memory from the current process (like the return action of a shared bicycle)

Prototype: int shmdt(const void *shm_addr);

Parameter description: shm_addr: the address pointer returned by shmat

Return value: If the operation is successful, it will return "0", and if it fails, it will return "-1"

Leaving shared memory does not mean deleting it, it's just that the current process can no longer access it.

4. shmctl function - delete

Function: control function of shared memory (generally not used, because data can be shared and can be overwritten , no need to delete)

原型:int  shmctl(int shm_id,int command,struct shmid_ds *buf);

Parameter Description:

  • shm_id: shared memory identification code returned by shmget
  • command: Action to be taken (three values: IPC_STAT, IPC_SET, IPC_RMID)
  • buf: Points to a data structure that holds the mode state and access rights of shared memory

Return value: If the operation is successful, it will return "0", and if it fails, it will return "-1"

 Memory operations:

  • memset usually initializes the newly applied memory (empty - bzero function)
  • memcpy memory copy, just copy the data, the original data will not be emptied

4. Examples

        Create two applications, one for reading and one for writing

1. Code

#include <iostream>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
using namespace std;

//写端

typedef struct student
{
	char stuid[10];
	char name[20];

}STU;
int main()
{
	void* shmaddr = NULL;
	int shmid = 0;

	STU stu1 = { "1001","zqw"};
	//创建
	shmid = shmget((key_t)1001,2048,IPC_CREAT|0777);

	if (shmid == -1)
	{
		perror("shmget  error");
	}
	else
	{
		//连接共享内存 获取到共享内存的首地址shmaddr
		shmaddr = shmat(shmid,NULL,0);

		//写入数据  = 内存拷贝
		memcpy(shmaddr, &stu1,sizeof(STU));

		/*cout <<"res_stu  id" << res_stu.stuid<< endl;
		cout << "res_stu  name" << res_stu.name << endl;*/

		//断开共享内存的连接
		shmdt(shmaddr);
	}

	return 0;
}

//读端

typedef struct student
{
	char stuid[10];
	char name[20];

}STU;
int main()
{
	void* shmaddr = NULL;
	int shmid = 0;

	STU res_stu = { 0 };
	//创建
	shmid = shmget((key_t)1001, 2048, IPC_CREAT | 0777);

	if (shmid == -1)
	{
		perror("shmget  error");
	}
	else
	{
		//连接共享内存 获取到共享内存的首地址
		shmaddr = shmat(shmid, NULL, 0);

		//读取数据  = 内存拷贝
		memcpy(&res_stu, shmaddr, sizeof(STU));

		cout << "读端  id = " << res_stu.stuid << endl;
		cout << "读端  name = " << res_stu.name << endl;

		//断开共享内存的连接

		shmdt(shmaddr);
	}

	return 0;
}

2. Running results 

  • Because the data is not changed, cleared, etc. on the read side, it is just a simple copy, so the data in the shared memory is still there, and the result of reading multiple times is still the same
  • When the process ends, the shared memory is still there, indicating that the shared memory is directly managed by the operating system rather than the process.
  • Shared memory is enough to use, it will occupy memory after creation until you delete it manually

 Please indicate the source

Cross-platform (Linux) development based on VS2019 C++ (1.5) - shared memory

Guess you like

Origin blog.csdn.net/hml111666/article/details/123697406