【Linux】System V Shared Memory

foreword

content

System V, once also known as AT&T System V, is one of many versions of the Unix operating system

System V introduces three high-level inter-process communication mechanisms: message queues, shared spaces, and semaphores

Shared memory is the fastest way of inter-process communication. The reason is that the shared area of ​​the address space of the communicating process pcb is mapped to a piece of physical memory at the same time, and the above data is directly found and accessed through the virtual address; these inter-process data transfer不再涉及到内核的系统接口的调用

After applying for shared memory, process 1 and process 2 respectively attach the corresponding shared memory to their own address space, and can communicate normally.

For pipe-based inter-process communication, system interfaces such as read and write need to be called. The write end first writes data to the kernel's file buffer, and the read end reads from the buffer. These operations all call the system interface.

In other words, processes no longer pass each other's data by executing system calls that go into the kernel.

insert image description here

1. Shared memory data structure

struct shmid_ds {
    
    
	struct ipc_perm shm_perm; /* operation perms */
	int shm_segsz; /* size of segment (bytes) */
	__kernel_time_t shm_atime; /* last attach time */
	__kernel_time_t shm_dtime; /* last detach time */
	__kernel_time_t shm_ctime; /* last change time */
	__kernel_ipc_pid_t shm_cpid; /* pid of creator */
	__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
	unsigned short shm_nattch; /* no. of current attaches */
	unsigned short shm_unused; /* compatibility */
	void *shm_unused2; /* ditto - used by DIPC */
	void *shm_unused3; /* unused */
};

2. Shared memory function

  • Create shared memory
int shmget(key_t key, size_t size, int shmflg);

Parameter
key: the name of the shared memory segment
size: the size of the shared memory
shmflg: consists of nine permission flags, their usage is the same as the mode flag used when creating a file
Return value: successfully returns a non-negative integer, that is, the shared memory The identification code of the memory; on failure returns -1
on shmflg:
insert image description here

  • Generate key
    The key is obtained by the ftok function, and returns a unique identification code of the shared memoryshmid
key_t ftok(const char *pathname, int proj_id);
  • Attach the shared memory segment to the process address space
void *shmat(int shmid, const void *shmaddr, int shmflg);

Parameter
shmid: shared memory identifier
shmaddr: specify the address of the connection
shmflg: its two possible values ​​are SHM_RND and SHM_RDONLY, generally set to 0
Return value: successfully returns a pointer, similar to malloc opening up space on the heap; failure returns -1

  • Unbind process address space from shared memory
int shmdt(const void *shmaddr);

Parameter
shmaddr: the pointer returned by shmat
Return value: 0 if successful; -1 if failed.
Note: Detaching the shared memory segment from the current process does not mean deleting the shared memory segment.
The ipc resource will not be released when the process exits, but will follow the process. The kernel, either shut down, or
free shared memory using the system interface free command:ipcrm shmid

  • Used to control shared memory
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

Parameter
shmid: shared memory identification code returned by shmget
cmd: action to be taken (there are three possible values)
buf: pointing to a data structure that saves the mode status and access rights of shared memory
Return value: success returns 0; failure returns -1
insert image description here

3. Command line view shared memory

ipcs -m

insert image description here
shmid : shared memory number
owner : creator
perms : permission
bytes : size
nattch : how many processes are connected
status : where "dest" is displayed, indicating that the shared memory segment has been deleted, but there are still users using it, when the mode of this segment of memory "dest" is displayed when the field is set to SHM_DEST.

4. Experiment: server and client communication

Experimental phenomena
insert image description here

  • common.h
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#define PATH_NAME  "/root/class101/linux/lesson20/sharememory" 
#define PROJ_ID 18733213
#define SIZE 4097
  • server.c
#include "common.h"
int main() {
    
    
  key_t key = ftok(PATH_NAME, PROJ_ID);
  if(key == -1) {
    
    
    perror("ftok");
    return 1;
  }

  printf("key: %x\n", key);

  int shmid = shmget(key, SIZE, IPC_CREAT|IPC_EXCL|0644);

  if(shmid == -1) {
    
    
    perror("shmget");
    return 2;
  }

  printf("shmid: %d\n", shmid);
  sleep(5);


  char* start = (char*)shmat(shmid, NULL, 0);
  if(start == (void*)-1) {
    
    
    perror("shmat");
    return 3;
  }
  printf("shmat success...\n");
  sleep(5);
  while(1) {
    
    
    printf("%s\n", start);
    sleep(1);
  }


  shmdt(start);
  sleep(5);
  shmctl(shmid, IPC_RMID, NULL);
  return 0;
}
  • client.c
#include "common.h"
int main(){
    
    
  
  key_t key = ftok(PATH_NAME, PROJ_ID);
  if(key == -1) {
    
    
    perror("ftok");
    return 1;
  }

  int shmid = shmget(key, SIZE, IPC_CREAT);
  if(shmid == -1) {
    
    
    perror("shmget");
    return 2;
  }

  sleep(5);
  char* start = (char*)shmat(shmid, NULL, 0);
  if(start == (void*)-1) {
    
    
    perror("shmat");
    return 3;
  }
  sleep(5);


  char ch = 'A';
  while(ch<='Z') {
    
    
    start[ch-'A'] = ch;
    ch++;
    sleep(1);
  }

  shmdt(start);
  printf("%x\n", key);
  return 0;
} 
  • Makefile
CC=gcc
all: server client
server: server.c
	$(CC) -o $@ $^
client: client.c
	$(CC) -o $@ $^
.PHONY: clean
clean: 
	rm -f server client

Since the server prints in an infinite loop, it is finally forced to manually release the shared memory:
insert image description here

ipcrm -m 327680

5. Note/Reiteration

1. Shared memory features

Shared memory 生命周期随OS
Operation 不提供任何同步与互斥of 双方彼此独立
shared memory. Shared memory is used in all inter-process communication. 速度最快的
The recommended size for creating shared memory is an integer multiple of 4KB, otherwise the system will be aligned according to 4KB.

二、key vs shmid

key: It is a unique key value generated by the user layer. The core function is to distinguish uniqueness and cannot be used to operate IPC resources.
shmid: It is an IPC resource identifier returned by the system to us, which is used to operate IPC resources.

  • How do you ensure that multiple processes see the same piece of shared memory?
    Unique distinction by Key
  • How to ensure that A and B use the same Key?
    key_t ftok(const char* pathname, int proj_id)

3. System interface

In the system, the command to view ipc isipcs

所有ipc资源都是随内核Yes, it will not be automatically released when the process exits, unless the interface is called to release / OS restart when the process exits

command release ipc

ipcrm -m shmid

Fourth, the routine

// create key

key_t ftok(pathname, proj_id);

// create shared memory

int shmid = shmget(key, SIZE, IPC_CREAT  | IPC_EXCL | 0644);

// shared memory hook process

char* start = shmat(shmid, NULL, 0);

// unlink

shmdt(start);

// freed

shmctl(shmid, IPC_RMID, NULL);

Guess you like

Origin blog.csdn.net/m0_52640673/article/details/123280222