System 5 shared memory

1. Introduction to shared memory:

        Shared memory is the most efficient method of inter-process communication. Processes can directly read and write memory without any copy of data.
         In order to exchange information between multiple processes, the kernel sets aside a memory area that can be mapped into its own private address space by the process that needs to access it.
        The process can directly read and write this memory area without copying the data, thus greatly improving efficiency.
        Since multiple processes share a section of memory, they also need to rely on some kind of synchronization mechanism, such as mutexes and semaphores.

2. Characteristics of shared memory:      

        2.1 Shared memory is the fastest way to share data between processes. When a process writes data to a shared memory area, all processes sharing this memory area can immediately see the contents.

        2.2 One thing to note when using shared memory is the mutual exclusion of access to a given storage area between multiple processes. If a process is writing data to the shared memory area, other processes should not read or write the data until it completes this operation.

3. Frame diagram:

4. Shared memory API analysis:

    4.1 Create or obtain shared memory:    
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:
     创建或获取共享内存
参数:
     1> key:密钥    一组16进制的地址
        1>自动获取:IPC_PRIVATE:系统自动创建分配共享内存
            弊端:永远都找不到同一块内存,不断创建新的共享内存,不采用
        2>手动获取:
            采用ftok函数
            #include <sys/types.h>
            #include <sys/ipc.h>
            key_t ftok(const char *pathname, int proj_id);
                  功能: 
                      手动创建或获取key 
                                    
                 参数: 
                      1>pathname:工程文件名(带路径)
                      2>proj_id :工程代号 
                                     
                 返回值: 
                       成功返回key 
                 失败返回-1,并设置错误码
                //只要参数不变化,总可以找到同一key

    2>size:共享内存大小
    3>shmflg:使用权限:
        IPC_CREAT|0666
返回值:
    成功返回shmid 
    失败返回-1,并设置错误码




ftok: Function: Create a unique shared memory identifier in the kernel so that the kernel can identify a unique shared memory or semaphore or message queue. 

 

 

        4.2 Contribution memory mapping:
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
     将共享内存映射到用户空间(进程)
参数:
     1>shmid:共享内存ID 
     2>shmaddr:你想要映射到的地方:NULL  自行寻找
     3>shmflg:0 可读可写

返回值:
       成功返回映射到的地址
       失败返回(void *)-1,并设置错误码
        4.3 Unmapping
shmdt
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
功能: 
    解除映射操作 
                    
参数: 
    shmaddr:需要解除的地址 
                    
返回值: 
      成功返回0
      失败返回-1,并设置错误码
        4.4 Delete shared memory
 4>删除共享内存 
    shmctl  --->共享内存操作 
    #include <sys/ipc.h>
    #include <sys/shm.h>
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    功能: 
        对共享内存进行操作  
        PS:删除只是其中一环
                           
    参数: 
         1>shmid:需要操作的共享内存ID号 
         2>cmd:删除共享内存操作:
              IPC_RMID:删除共享内存 
                            
         3>buf:结构体指针:用来赋值的操作
              IPC_RMID:NULL 
                            
    返回值: 
             IPC_RMID:成功返回0 
             失败返回-1,并设置错误码

5. Check the shared memory in the system

 ipcs -m 

6. Delete shared memory in the system

ipcrm -m 共享内存ID

7. Shared memory example:

Write on one end:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
    //创建密钥
    key_t key=ftok("pause.c",1);
    if(key<0){
        perror("ftok");
        return -1;
    }
    
    printf("key:%#x\n",key);
    
    //1>创建或获取共享内存
    int shmid=shmget(key,200,IPC_CREAT|0666);
    //int shmid=shmget(IPC_PRIVATE,200,IPC_CREAT|0666);
    if(shmid<0){
        perror("shmget");
        return -1;
    }
    printf("共享内存ID号为:%d\n",shmid);
    
    //2>将共享内存映射到用户空间
    void *addr=shmat(shmid,NULL,0);
    if(addr==(void *)-1){
        perror("shmat");
        return -1;
    }
    char *p=(char *)addr;//将万能指针型转化为char * 
    printf("进程的地址为:%p\n",p);
    
    //3>解除映射 
    int ret=shmdt(addr);
    if(ret<0){
        perror("shmdt");
        return -1;  
    }
    
    //4>删除共享内存 
    ret=shmctl(shmid,IPC_RMID,NULL);
    if(ret<0){
        perror("shmctl");
        return -1;  
    }
    
    //通信?
    //while(1){
    scanf("%s",p);//此时,p为野指针,发生段错误 
    //}
    return 0;
}

One end reads:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
    //创建密钥
    key_t key=ftok("pause.c",1);
    if(key<0){
        perror("ftok");
        return -1;
    }
    
    printf("key:%#x\n",key);
    
    
    //1>创建或获取共享内存
    int shmid=shmget(key,200,IPC_CREAT|0666);
    //int shmid=shmget(IPC_PRIVATE,200,IPC_CREAT|0666);//最好不使用
    if(shmid<0){
        perror("shmget");
        return -1;
    }
    printf("共享内存ID号为:%d\n",shmid);
    
    
    //2>将共享内存映射到用户空间
    void *addr=shmat(shmid,NULL,0);
    if(addr==(void *)-1){
        perror("shmat");
        return -1;
    }
    char *p=(char *)addr;//将万能指针型转化为char * 
    printf("进程的地址为:%p\n",p);
   
    //3>通信?
    while(1){//共享内存是不会阻塞的
    printf("%s\n",p);
    }
    return 0;

Summarize:


          Shared memory: Use the memory area to map the space of two processes. The two processes transfer data through the memory, directly input to the memory area, and directly output. It is the most efficient because when operating the memory area, if the operation is not rigorous, the segments encountered There may be relatively many errors. The memory area is directly input and output, so there is no blocking concept 
            while(1)//is not available and requires other means.

Guess you like

Origin blog.csdn.net/apple_71040140/article/details/132511979