Shared memory of Linux programming

Source: Internet
Author: User
Tags new set posix

Linux supports two different ways of sharing memory: System V and POSIX shared memory.

1. POSIX shared Memory 1.1 The origin of POSIX shared memory

Insufficient System V shared memory and shared file mappings:

    • The System V shared memory model uses keys and identifiers that are inconsistent with the standard UNIX I/O model's use of filenames and descriptors. This difference means a whole new set of system calls and commands is required to use system V shared memory.
    • Using a shared file mapping for IPC requires that you create a disk file, even if you do not need to persist storage for the shared zone. In addition to the inconvenience caused by the need to create files, this technique also brings some file I/O overhead.

Based on these deficiencies, POSIX.1B defines a new set of shared memory Api:posix shared memory.

1.2 POSIX Shared Memory overview

POSIX shared memory allows unrelated processes to share a mapped area without creating a corresponding mapping file. Linux supports POSIX shared memory starting from kernel 2.4.

Many UNIX-like implementations employ a file system to identify shared memory objects. Some UNIX implementations create a shared memory object name as a file at a special location on a standard file system. Linux uses a dedicated TMPFS file system that is mounted in the/DEV/SHM directory. This filesystem has kernel persistence-it contains shared memory objects that persist, even if no processes currently open it, but these objects are lost after the system shuts down.

The total amount of memory occupied by POSIX shared memory areas on the system is limited by the size of the underlying TMPFS file system. This file system is typically mounted at startup with a default size, such as a large MB. If necessary, the Superuser can mount-o remount,size= by using the command.

Process for using POSIX shared memory objects:

    • Use the Shm_open () function to open an object that corresponds to the specified name. The Shm_open () function is similar to the open () system call, which creates a new shared object or opens an existing object. As a function result, Shm_open () returns a file descriptor that references the object.
    • Pass in the file descriptor obtained in the previous step to the mmap () call and specify map_shared in its flags parameter. This maps the shared memory object into the virtual address space of the process. As with other usages of mmap (), once you have mapped an object, you can close the file descriptor without affecting the mapping. Then, it may be necessary to keep this file descriptor open for subsequent fstat () and Ftruncate () calls to use this file descriptor.
1.3 Creating a shared memory object

The Shm_open () function creates and opens a new shared-memory object or opens an existing object. The arguments to the incoming shm_open () are similar to the parameters of the incoming open ().

#include <sys/mman.h>#include <sys/stat.h>        /* For mode constants */#include <fcntl.h>           /* For O_* constants */int shm_open(const chart *name, int oflag, mode_t mode);        Returns file descriptor on success, or -1 on error.        Link with -lrt.

The name parameter identifies the shared memory object that you want to create or open. The Oflag parameter is a bitmask that alters the invocation behavior.

The bit value of the Oflag parameter:

    • O_creat: When an object is not present, an object is created, a new shared memory object is initially length 0, and the size of the object can be set using Ftruncate.
    • O_EXCL: An object is created with O_creat mutex, that is, if the o_creat has been specified and a shared memory object with the specified name already exists, an error is returned.
    • O_rdonly: Open read-only access.
    • O_RDWR: Open read-write access.
    • O_trunc: truncates the object length to zero.

When a new shared memory object is created, its ownership and group ownership will be set according to the valid user and group ID of the process calling Shm_open (), and the object permissions will be set according to the mask value set in the mode parameter. The bit value that the mode parameter can take is the same as the permission bit value on the file. As with the open () system call, the permission mask in mode will take a value based on the umask of the process. Unlike open (), the mode parameter is always required when calling Shm_open (), and this parameter value is specified as 0 when new objects are not created.

The file descriptor returned by Shm_open () sets the close-on-exec tag, so the file descriptor is automatically closed when the program executes an exec ().

When a new shared memory object is created, its initial length is set to 0. This means that after creating a new shared memory object, it is usually necessary to call Ftruncate () before calling Mmap () to set the size of the object. You may also need to use Ftuncate () to expand or shrink the shared memory object as required after Mmap () is called.

When you extend a shared memory object, the newly added bytes are automatically initialized to 0.

At any time, you can use Fstat () on the file descriptor returned by Shm_open () to get a stat structure whose fields contain information related to this shared memory object, including its size (st_size), Permissions (St_mode), owner (St_ UID) and group (St_gid).

Use Fchmod () and Fchown () to modify the permissions and ownership of shared memory objects individually.

Example program: PSHM_CREATE.C

The program creates a shared memory object of the size specified by the command parameter and maps the object into the virtual address space of the process.

#include<stdio.h>#include<string.h>#include<fcntl.h>#include<sys/mman.h>#include<sys/stat.h>#include <unistd.h>#include <stdlib.h>int main(int argc, char *argv[]){    int flags, opt, fd;    mode_t perms;    size_t size;    void *addr;        /* Create shared memory object and set its size */    fd = shm_open(argv[1], O_RDWR|O_CREAT, 0777);    if (fd == -1)     {        printf("shm_open failed");        exit(-1);    }        if (ftruncate(fd, 10000) == -1)    {        printf("ftruncate failed");        exit(-1);    }        /* Map shared memory object */    addr = mmap(NULL, 10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);    if (addr == MAP_FAILED)     {        printf("mmap failed");        exit(-1);    }        exit(EXIT_SUCCESS);}

The above program creates a 10000-byte shared memory object:

# gcc pshm_create.c -o pshm_create -lrt# ./pshm_create demo_shm# ls -l /dev/shm/demo_shm -rwxr-xr-x 1 root root 10000 Jun 16 03:34 /dev/shm/demo_shm
1.4 Using shared memory objects pshm_write.c

Copies the data into a POSIX shared memory object.

  #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h>#    include<sys/stat.h> #include <unistd.h> #include <stdlib.h>int main (int argc, char *argv[]) {int FD;    size_t Len;        Char *addr;     /* Open Existing Object */FD = Shm_open (argv[1], O_RDWR, 0);        if (fd = =-1) {printf ("Shm_open failed");    Exit (-1);    } len = strlen (argv[2]);        /* Resize object to hold String */if (ftruncate (fd, len) = =-1) {printf ("Ftruncate failed");    Exit (-1); } addr = Mmap (NULL, Len, prot_read|    Prot_write, map_shared, FD, 0);        if (addr = = map_failed) {printf ("mmap FAILED");    Exit (-1);        } if (Close (FD) = =-1) {printf ("Close failed");    Exit (-1);    } printf ("Copying%ld bytes\n", (long) Len);    /* Copy string to Shared memory */memcpy (addr, argv[2], Len); Exit (exit_success);}  

Demo_shm writes data to a shared memory object created to 1.3:

# gcc pshm_write.c -o pshm_write -lrt# ls -l /dev/shm/demo_shm -rwxr-xr-x 1 root root 10000 Jun 16 03:34 /dev/shm/demo_shm# ./pshm_write demo_shm ‘hello‘copying 5 bytes# ls -l /dev/shm/demo_shm -rwxr-xr-x 1 root root 5 Jun 16 03:46 /dev/shm/demo_shm
Pshm_read.c

Copies data from a POSIX shared memory object.

  #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h>#    include<sys/stat.h> #include <unistd.h> #include <stdlib.h>int main (int argc, char *argv[]) {int FD;    Char *addr;        struct STAT sb;     /* Open Existing Object */FD = Shm_open (argv[1], o_rdonly, 0);        if (fd = =-1) {printf ("Shm_open failed");    Exit (-1);        }/* Use shared memory object size as length argument for mmap () * And as number of bytes to write () */        if (Fstat (fd, &SB) = =-1) {printf ("Fstat failed");    Exit (-1);    } addr = Mmap (NULL, Sb.st_size, Prot_read, map_shared, FD, 0);        if (addr = = map_failed) {printf ("mmap FAILED");    Exit (-1);        } if (Close (FD) = =-1) {printf ("Close failed");    Exit (-1);    } write (Stdout_fileno, addr, sb.st_size);    printf ("\ n"); Exit (exit_success);}  

Displays the string that was just written to the shared memory object DEMO_SHM:

# gcc pshm_read.c -o pshm_read -lrt# ./pshm_read demo_shmhello
1.5 Deleting a shared memory object

POSIX shared memory objects have kernel persistence, meaning they persist until they are displayed for deletion or for system restarts. When you no longer need a shared memory object, you should use Shm_unlink () to remove it.

#include <sys/mman.h>int shm_unlink(const char *name);        Returns 0 on success, or -1 on errorLink with -lrt.

The Shm_unlink () function removes the shared memory object specified by name. Deleting a shared memory object does not affect an existing mapping of the object (it remains valid until the appropriate process calls Munmap () or terminates), but prevents subsequent shm_open () calls from opening the object. Once all processes are mapped to this object, the object is deleted and the contents are lost.

Pshm_unlink.c
#include <fcntl.h>#include <sys/mman.h>#include <stdlib.h>#include <stdio.h>int main(int argc, char *argv[]){    if (shm_unlink(argv[1]) == -1)    {        printf("shm_unlink failed");        exit(-1);    }        exit(EXIT_SUCCESS);}

Delete the shared memory object created above DEMO_SHM:

# gcc pshm_unlink.c -o pshm_unlink -lrt# ./pshm_unlink demo_shm

Shared memory of Linux programming

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.