[Shared Memory] Shared Memory and process communication

Table of contents

1. Overview of shared memory

2. Shared memory operations

1) Obtain a shared storage identifier: shmget function

2) Shared memory mapping (attach): shmat function

3) Detach shared memory mapping (detach): shmdt function

4) Shared memory control: shmctl function

Summarize:


1. Overview of shared memory

        Shared memory allows two or more processes to share a given storage area.

Features of shared memory:

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) What should be noted 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.

Shared memory diagram:

        Shared memory is the most efficient inter-process communication method. The reason is that the process operates directly on the physical memory and maps the physical address to the user process. Therefore, as long as the operation on its address is performed, the physical address is directly operated.

2. Shared memory operations

The shared memory limitations in ubuntu12.04 are as follows:

  • Minimum number of bytes in shared memory: 1
  • Maximum number of bytes in shared storage area: 32M
  • Maximum number of shared memory areas: 4096
  • The maximum number of shared storage areas that each process can map: 4096

Use shell commands to operate shared memory:

View shared memory: ipcs -m

Delete shared memory: ipcrm -m shmid

1) Obtain a shared storage identifier: shmget function

shmget function:

#include<sys/ipc.h>

#include<sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

Function: Create a shared memory

parameter:

        key: key value, the unique key value determines the unique shared memory

        size: the size of the shared memory created

        shmflg: shared memory access permissions

                        Generally IPC_CREAT | 0777

return value:

        Success: ID of shared memory

        Failure: -1 

Code example:

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

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    printf("shmid = %d\n", shmid);
    system("ipcs -m");

    return 0;
}

Execution screenshot:

2) Shared memory mapping (attach): shmat function

shmat function:

#include<sys/types.h>

#include<sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

Function: Map shared memory

parameter:

        shmid: ID of shared memory

        shmaddr: mapped address, set to NULL for automatic allocation by the system

        shmflg: flag bit

                0: Shared memory has read and write permissions

                SHM_RDONLY: read only

return value:

        Success: mapped address

        Failure: -1

3) Detach shared memory mapping (detach): shmdt function

shmdt function:

#include<sys/types.h>

#include<sys/shm.h>

int shmdt(const void *shmaddr);

Function:

        Unmap shared memory

parameter:

        shmaddr: mapped address, return value of shmat

return value:

        Success: 0

        Failure: -1 

Shared memory mapping and unmapping code examples: 

write.c

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

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    char* text;
    if ((text = shmat(shmid, NULL, 0)) == (void*)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    //写入
    strcpy(text, "hello world");
    if (shmdt(text) == -1)
    {
        perror("fail to text");
        exit(1);
    }
    system("ipcs -m");
    return 0;
}

read.c

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

int main()
{
    //创建共享内存
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    //      system("ipcs -m");
    //映射
    char* text;
    if ((text = shmat(shmid, NULL, 0)) == (void*)-1)
    {
        perror("fail to shmat");
        exit(1);
    }
    printf("text = %s\n", text);
    //解除映射
    if (shmdt(text) == -1)
    {
        perror("fail to shmdt");
        exit;
    }
    system("ipcs -m");
    return 0;
}

Execution screenshot: 

 

4) Shared memory control: shmctl function

shmctl function:

#include<sys/ipc.h>

#include<sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

Function:

        Set or get the properties of shared memory

parameter:

        shmid: ID of shared memory

        cmd: command to perform operations

                IPC_STAT Gets the attributes of shared memory

                IPC_SET sets the properties of shared memory

                IPC_RMID delete shared memory

        shmid_ds: attribute structure of shared memory

return value:

        Success: 0

        Failure: -1

Code example:

#include<stdlib.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main()
{
    key_t key;
    if ((key = ftok(".", 100)) == -1)
    {
        perror("fail to ftok");
        exit(1);
    }
    int shmid;
    if ((shmid = shmget(key, 500, IPC_CREAT | 0666)) == -1)
    {
        perror("fail to shmget");
        exit(1);
    }

    printf("shmid = %d\n", shmid);
    //删除共享内存
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("fial to shmid");
        exit(1);
    }
    system("ipcs -m");
    return 0;
}

Execution screenshot:

Summarize:

        As an efficient inter-process communication mechanism, shared memory plays an important role in a multi-process environment with its unique advantages. It allows multiple processes to directly access the same memory area, thereby realizing fast sharing and exchange of data and significantly improving system performance . However, this also brings challenges of data synchronization and concurrency control. We need to combine locks, semaphores and other synchronization technologies to solve these problems.

        Overall, shared memory is a powerful and flexible tool, but it needs to be used carefully and effectively to ensure program correctness and stability.

Guess you like

Origin blog.csdn.net/crr411422/article/details/131421891