Shared Memory summary

For the study of the origin of shared memory and "Linux high-performance servers," shared memory to read and understand the chat server code! However, in practice, do the server side, we rarely promising 每一个客户连接分配一个进程来处理相应的写或者读事件approach. He created the server in the parent shared memory is good, when connected to a client, fork a process to handle each sub-process client data is written to the corresponding location of its management shared memory, and use two-way communication pipeline inspection signal, through a series of signal processing to the client disconnects, the disconnect parent client corresponding to the recovery process. The main program is simple to use shared memory, and does not involve the synchronization of shared memory.
ps. 菜鸡想吐槽I just do not understand why not book through a small example Here is a simple application in terms of shared memory, but directly to the use of shared memory to a epoll+多进程+信号server. Thus, to speak of shared memory, it allows readers to chew on a Code of nearly 400! Look at the people heart to tears! He only introduces some of the shared memory API does not say that some of his principles like!


  • Shared memory brief

Shared memory to Simple talk is to achieve a quick IPC mechanism, and now we think about the way IPC to achieve what, say what I know:

  • Pipes, named pipes can communicate, anonymous pipes between the different processes can only realize the communication between parent and child.
  • Message queues, I am more familiar, like a message list maintained by the kernel to achieve.
  • Shared memory.

These are far I know IPC mechanism, why fast shared memory? For the first three, go through:
数据从文件写到进程控制的内存-> 操作-> 将数据cp到内核-> 通知对话的进程进行读取-> 对端进程从内核读取-> 操作...
<Be aware that these steps require a lot of system calls to complete the operation, consume system resources, reducing efficiency! >
The shared memory?
If not, then shared memory space.
创建共享内存对象(This simply means that a new file) -> 指定文件的控制空间大小(we create a shared memory certainly have to have a certain range of it!) -> 通过映射,将创建好的共享内存对象映射到内存页表, this time with the corresponding shared memory segment in physical memory, as follows ( 画的是大概的映射机制,由于认识有限,不敢做过多描述,有披露的话,还请指出):

Here Insert Picture Description
So, we can understand why the shared memory fast! When a different process to read and write data directly to this section of memory to operate, eliminating the part of the system calls, fast communications between processes, and convenient.
Of course, there must be a defect, because it involves multiple processes on the same section of memory read or modify operation, because there is no corresponding shared memory protection lock mechanism to limit the synchronization of different processes. Therefore, the use of shared memory and in line with other inter-process communication mechanism as a lock or conditions, to achieve synchronization between processes!

. ps learning shared memory, inexplicably produced a series of questions, share:
What is the process block (PCB)?
What is the process address space?
What memory page tables are?

Really I can not think, if more thought, I could not finish the school this shared memory. Through access to information, simply come to the following conclusions.

Process block, the recording process is the kernel state data structure information and resources, i.e. task_struct.
User-space virtual address space of the process, process, 4GB size! If want to know more I recommend this article
memory page table to match the virtual and physical memory of things.

First make a simple understanding, if get to the bottom, then it really Chaogang up!


  • Use of shared memory

共享内存的POSIX方法

<sys/mman.h>
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
int munmap(void* start,size_t length);

Here is a small example application:
between two processes are not synchronized, so the run will be a dirty read value in memory. The key to understand the process of creating a shared memory. The reading process directly find the location of shared memory can be read by mmap, and did not create too much trouble!

#include <iostream>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<sys/mman.h>
#include<memory.h>
#include"socketfd.h"

using namespace std ;
#define SHARED_SIZE 120
const char*shm_name = "/myshm" ;
char* shm_add ;
void handler(int arg) ;

int main()
{

    cout << "创建共享内存" << endl ;
    //*****使用shm_open 来创建共享内存的对象,使用方法和open相同
    int sh = shm_open(shm_name, O_CREAT|O_RDWR|O_TRUNC, 0677)  ;

    //*****指定共享内存对象控制的空间大小
    ftruncate(sh, SHARED_SIZE) ;
    
    //将所创建的共享内存对象映射到内存页上
    //第一个参数NULL,表示让操作系统决定要关联的共享内存地址
    //第二个参数是共享内存的大小
    //第三个参数指定要要进行的操作,写数据,读数据.....
   //第四个参数指定改段内存是共享的,map_shared
   //sh文件描述符
   //*****被映射内容的起点位置,从共享内存0开始
    char* a = (char*)mmap(NULL, SHARED_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, sh, 0);
    memset(a, SHARED_SIZE, '\0') ;
    shm_add = a ;
    assert(a != MAP_FAILED) ;
    //*****关掉文件
    close(sh) ;
    //往共享内存中写数据
    const char* shm_data = "hello_world!" ;
    int len = strlen(shm_data) ;
    signal(SIGINT, handler) ;

    cout <<"写数据:"<<"" ;
    int i =0 ;
    for(;;)
    {
        memcpy(a, shm_data+i, len) ;
        cout <<*a<<endl ; 
        sleep(1) ;
        i++ ;
        if(i == len)break ;
    }
    //******分离进程与共享内存对象
    munmap(shm_add, SHARED_SIZE) ;
}

void handler(int arg)
{
    munmap(shm_add, SHARED_SIZE) ;
}
#include <iostream>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<sys/mman.h>
#include<memory.h>
#include"socketfd.h"
using namespace std ;
#define SHARED_SIZE 120
const char*shm_name = "/myshm" ;
char* shm_add ;
void handler(int arg) ;
int main(int argc, char**argv)
{

    int sh = shm_open(shm_name, O_RDWR, 0677)  ;
    
    char* a = (char*)mmap(NULL, SHARED_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, sh, 0);
    signal(SIGINT, handler) ;
    shm_add = a ;
    int i = 0 ;
    cout << "读数据:" << endl ;
    while(1)
    {
        cout << *(a+i) <<endl  ;
        i++ ;
        sleep(1) ;
    }
    munmap(shm_add, SHARED_SIZE) ;
    return 0;
}

void handler(int arg)
{
    munmap(shm_add, SHARED_SIZE) ;
}
//记得加指定连接选项 -lrt
 g++ mmap.cpp -o write -lrt
 g++ mmap_read.cpp -o read -lrt

These are temporarily some small sum, followed with the increase in awareness, we will add some shortcomings!

下面是另一种方法

Reference blog

Guess you like

Origin blog.csdn.net/qq_41681241/article/details/88910562