What is shared memory

Shared memory refers to a large amount of memory that can be accessed by different cpus in a multi-processor computer system. Because multiple cpus need to access the memory quickly, the memory needs to be cached. When any cached data is updated, the shared memory needs to be updated immediately, because other processors may also access it, or different processors may use different data.

Shared memory is the communication method between multiple processes under Unix. This method is usually used for the communication between multiple processes of a program. In fact, multiple programs can also pass information through shared memory.

The characteristics of

Shared memory, which allows multiple processes to access the same memory space, is the fastest form of IPC available. It is designed for the low efficiency of other communication mechanisms.

However, there is no internal shared memory mutually exclusive access mechanism, so it is often used in combination with other communication mechanisms, such as semaphores, to achieve synchronization and mutual exclusion between processes.

Involves the function

  • Ftok: An ID must be specified when the system establishes IPC communications (message queues, semaphores, and shared memory)

    The header file

    #include <sys/types.h>
    #include <sys/ipc.h>
    Copy the code

    The function prototype

    Key_t ftok(const char * fname, int id) fname: specifies the file name (an existing file name), usually using the current directory, for example:"."Id: ID is a sub-id. It is an int, but only 8bits(1-255) are used. In a normal UNIX implementation, the return value of key_t is obtained by taking the inode number of the file, preceded by a subnumber. For example, if the specified inode number is 65538, converted to hexadecimal 0x010002, and the specified ID value is 38, converted to hexadecimal 0x26, the final key_t return value is 0x26010002. You can run the ls -i command to query the id of a file index node. After a file is deleted and rebuilt, the id is assigned by the operating system based on the usage of the file system at the time. Therefore, the id is different from the original.Copy the code
  • Shmget: Gets a shared memory identifier or creates a shared memory object and returns the shared memory identifier

    • The header file
    #include <sys/ipc.h>
    #include <sys/shm.h>
    Copy the code
    • The function prototype
    Int shmget(key_t key, size_T size, int SHMFLG) Key 0(IPC_PRIVATE) : a 32-bit integer greater than 0 that will create a new shared memory object. The operation depends on SHMFLG. Size An integer greater than 0: Specifies the size of the newly created shared memory, in bytes. 0: Specifies 0 when only the shared memory is obtained. SHMFLG 0: obtains the shared memory identifier. When shmflg&IPC_CREAT is true, a new shared memory is created if there is no shared memory with the same key value in the kernel. If there is such a Shared memory, returns the identifier of this Shared memory IPC_CREAT | IPC_EXCL: if the kernel does not exist in the key value and equal Shared memory, the key is to create a new Shared memory; If there is such a Shared memory is an error When used with IPC object access permissions | operation (e.g., 0600) carried out to determine the semaphore set access permissions function return value success: returns the Shared memory identifier error: 1, the reason for the error in the error in the error code EINVAL: Size smaller than SHMMIN or larger than SHMMAX EEXIST: indicates that the shared memory specified by the key is pre-created but already exists. EIDRM: indicates that the shared memory specified by the key has been deleted. ENOSPC: indicates that the value of the shared memory exceeds the maximum value allowed by the system (SHMALL) ENOENT: The shared memory indicated by key does not exist, and the IPC_CREAT bit is not set for SHMFLG. EACCES: no permission. ENOMEM: the core memory is insufficientCopy the code
  • Shmat: Connects to the shared memory whose identifier is SHmid. After the connection is successful, the shared memory area object is mapped to the address space of the calling process, which can be accessed as the local space

    • The header file
    #include <sys/types.h>
    #include <sys/shm.h>
    Copy the code
    • The function prototype
    Void *shmat(int shmid, const void *shmaddr, int SHMFLG) hmid: shmaddr: SHMFLG: SHM_RDONLY: indicates read-only mode. The other is read/write mode. The child process inherits the connected shared memory address.execThe child process then detach automatically from the connected shared memory address. After the process ends, the connected shared memory address will automatically detach (detach) function return value success: Attached shared memory address error: -1, the cause of the error is stored in errno Error code EACCES: No permission to connect to the shared memory in the specified way EINVAL: Invalid parameter shmid or shmaddr ENOMEM: Insufficient core memoryCopy the code
  • SHMDT: In contrast to the shmat function, SHMDT is used to disconnect the address of the shared memory attachment point, and to prevent the process from accessing the shared memory

    • The header file
    #include <sys/types.h>
    #include <sys/shm.h>
    Copy the code
    • The function prototype
    Int SHMDT (const void *shmaddr) This function call does not delete the shared memory area specified, but simply detach the current process function from the shared memory that was attached with shmat function. The return value of the current process function is success: 0 error: -1, the cause of the error is stored in error code EINVAL: Invalid parameter shmaddrCopy the code
  • SHMCTL: Controls the shared memory

    • The header file
    #include <sys/types.h>
    #include <sys/shm.h>
    Copy the code
    • The function prototype
    Int SHMCTL (int shmid, int CMD, struct shmid_ds *buf) shmid: CMD IPC_STAT: IPC_SET: Change the state of the shared memory, and copy the UID, GID, and mode in the shMID_ds structure specified by BUF to the IPC_RMID in the shmid_ds structure of the shared memory: Delete this shared memory buF: shared memory management structure. For details, see Shared memory kernel structure Definition Some functions Return value Success: 0 Error: -1, the cause of the error is stored in error error code EACCESS: CMD is IPC_STAT, there is no permission to read the shared memory EFAULT: buf points to an invalid memory address EIDRM: CMD or shmid EPERM: CMD is IPC_SET or IPC_RMID, but does not have sufficient permission to executeCopy the code

The sample code

shm_write.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>Int main(int argc, const char * argv[]) {key_t key = ftok(". /", 88); / / create the Shared memory, returns an id / / number 4, 2, and 1 said to read, write, and execute permissions / / user, group, other groups have belongs to read and write access int shmid = shmget (key, 8, IPC_CREAT | 0666); // IPC_CREAT: Create entryif key does not exist
    
    if (shmid == -1) {
        perror("shmget failed");
        //exit(0) indicates that the program exits normally,exit(1) /exit(-1) indicates that the program exits unexpectedly.exit(1); // SHMFLG: // SHMFLG: // SHMFLG: // Void *p = shmat(shmid, NULL, 0); SHM_RDONLY: indicates the read-only mode.if (p == (void *)-1) {
        perror("shmat failed");
        exit(2); } int *pp = p; *pp = 0x123456; *(pp + 1) = 0xffffff; // Remove the mappingif (shmdt(p) == -1) {
        printf("shmdt failed");
        exit(3);
    }
    
    printf("Unmapping successful, press Enter to destroy shared memory \n"); getchar(); //IPC_RMID: deletes the shared memoryif (shmctl(shmid, IPC_RMID, NULL)) {
        perror("shmctl failed");
        exit(4);
    }
    
    return 0;
}

Copy the code

shm_read.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>

int main() {// generate key key_t key = ftok()". /", 88); Int shmid = shmget(key, 0, 0); int shmid = shmget(key, 0, 0); shmFLg0: shmFLG0.if (shmid == -1) {
        perror("shmget failed");
        exit(1); Void *p = shmat(shmid, 0, 0);if (p == (void *)-1) {
        perror("shmat failed");
        exit(2); Int data1 = *(int *)p; int data2 = *((int *)p + 1);printf("Read from shared memory, %x and %x\n", data1, data2); // Remove the mappingif(shmdt(p) == -1) {
        perror("shmdt failed");
        exit(3);
    }
    
    
    return 0;
}
Copy the code

Compile the code

clang -o shm_write shm_write.c
clang -o shm_read shm_read.c
Copy the code

Execute the code

./shm_write
./shm_read
Copy the code