Shared memory of Linux process communication

Source: Internet
Author: User

Shared memory is a portion of physical memory that is shared by multiple processes. Shared memory is the quickest way to share data between processes, where a process writes data to a shared memory region, and all processes that share that memory area can immediately see the contents.


About the APIs used for shared memory

key_t Ftok (const char *pathname, int proj_id);
#在IPC中, we often use a key_t value to create or open semaphores, shared memory, and Message Queuing. This key_t is generated by the Ftok function.
Pathname: The specified file name, the file must be present and can be accessed
The integer value between proj_id:1~255.
For Ftok This function, the individual is not much use, first, the application may be used on different hosts, (for an environment, the file has not?) )。 2nd, if multiple processes accessing the same shared memory call Ftok this time period, pathname the specified file is deleted and recreated, then each process gets the key_t is different, the application does not error, but the purpose of data sharing is not reachable.




int Shmget (key_t key, size_t size, int shmflg);
The shmget is used to obtain the ID of the shared memory area, and if the specified shared area does not exist, the corresponding zone is created.
Key: The identifier for this shared memory. If it is a parent-child critical interprocess communication, this identifier is replaced with Ipc_private. If two processes do not have any relationship, the official argument is to use Ftok to generate a key (in view of the above introduction of Ftok, the practice of personal identity is to define one).
Size: This chunk of shared memory. (Number of bytes)
SHMFLG: is a set of flags.
Ipc_creat: If the shared memory does not exist, a shared memory is created.
IPC_EXCL: The new shared memory is established only if the shared memory does not exist, or an error occurs.
This is typically done for this parameter
#define PERM S_IRUSR | S_IWUSR | Ipc_creat
Then take PERM as SHMFLG.
The identifier for the shared memory was returned successfully, not successfully returned-1, and the errno was set.




void *shmat (int shmid, const void *shmaddr, int shmflg);
Used to establish a memory map (allows the process to establish contact with the specified shared memory, read and write data)
Shmid: The ID of the shared memory. (return value of Shmget function)
SHMADDR: Specifies the address location of the shared memory connection to the current process, usually empty, indicating that the system chooses the address of the shared memory.
SHMFLG: It's a group of Peugeot. Represents the operating mode of this process for this memory process. If the shm_rdonly is read-only mode, the other is read-write mode. This parameter is typically set to 0.
The start address of the shared memory is returned successfully, the failure returns-1, and the errno is set.


int SHMDT (const void *SHMADDR);
The shared memory pointer of the broken link. (This shared memory segment is not actually deleted from the kernel)
SHMADDR: Starting address of shared memory (return value of Shmat function)


int shmctl (int shmid, int cmd, struct shmid_ds *buf);
Controlling the use of shared memory
Shmid: The ID of the shared memory. (return value of Shmget function)
CMD: Control command. The following values are desirable:
Ipc_stat: Get the state of shared memory
Ipc_set: Changing the state of shared memory
IPC_RMID: Deleting shared memory
BUF: is a struct pointer, and when CMD is Ipc_stat, the acquired state is placed in the struct. If you want to change the state of shared memory, specify it with this struct.
struct SHMID_DS prototype
struct Shmid_ds {
struct Ipc_perm shm_perm; /* Operation permissions */
size_t Shm_segsz; /* Size (in bytes) of the shared memory segment */
time_t Shm_atime; /* The time the last process was attached to the segment */
time_t Shm_dtime; /* The time the last process left the segment */
time_t Shm_ctime; /* The last process modifies the time of the segment */
pid_t Shm_cpid; /* PID for creating shared memory segment processes */
pid_t Shm_lpid; /* PID of the last process to operate on this shared memory segment */
shmatt_t Shm_nattch; /* Number of processes currently attached to this shared memory segment */
...
};
Successfully returned 0, failed returns-1, and set errno.


Note!!!!!!!!! : After you use shared memory, the end program exits. If you are not using Shmctl () to remove shared memory in the program, be sure to remove the shared memory with the IPCRM command at the command line. If you don't care, it's always there.
Explain briefly the IPCS command and the IPCRM command.



Application Scenarios

    • Inter-process communication-producer consumer model
producer Processes and consumer process communications often use shared memory, such as a network server, after the access process receives packets, directly write to the shared memory, and wake up the processing process, the processing process from the shared memory read packets, processing. Of course, this solves the problem of mutual exclusion.
Sample program:
#ifndef shm_com_h_included# communication between parent and child processes can also use shared memory because the child processes and parent processes that are generated by the fork do not share the memory area. After the parent process starts, create a memory share, and then call Fork to create the child process. Finally, in the parent-child process to do memory mapping to achieve data sharing. Define Shm_com_h_included#include <stdio.h> #include <unistd.h> #include <string.h> #include < stdlib.h> #include <errno.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h > #include <sys/stat.h> #define PERM            s_irusr | S_IWUSR | Ipc_creat#define TEXT_SZ        2048struct shared_use_st{    int written_by_you;    Char SOME_TEXT[TEXT_SZ];};

/* The consumer program creates a shared memory segment and then connects it to its own address space (shared memory mapping) and we use a struct shared_use_st at the beginning of shared memory. There is a flag in the structure written_by_you, when there is data written in the shared memory, This flag is set. When this flag is set, the program reads the text from the shared memory, prints it out, and then clears the flag to indicate that the data has been read. We use a special string end to exit the loop. Next, the program detaches the shared memory segment and deletes it.    */#include "shm_com.h" int main (int argc, char** argv) {srand ((unsigned int) getpid ());    int runing = 1, shmid;    struct Shared_use_st *shared_stuff; if (Shmid = Shmget ((key_t) 8888, sizeof (struct shared_use_st), PERM)) = =-1) {fprintf (St            Derr, "%s%s%d\n", Strerror (errno), __file__, __line__);        return-1;             } if ((Shared_stuff = (struct Shared_use_st *) Shmat (shmid, 0, 0) = = (struct Shared_use_st *)-1) {            fprintf (stderr, "%s%s%d\n", Strerror (errno), __file__, __line__);        return-1;    } shared_stuff->written_by_you = 0;            while (runing) {while (shared_stuff->written_by_you = = 0) sleep (1); printf ("you wrote:%S ", Shared_stuff->some_text);            Sleep (rand ()% 4);            shared_stuff->written_by_you = 0;                if (strncmp (Shared_stuff->some_text, "End", 3) = = 0) {runing = 0; }} if (Shmdt (shared_stuff) = =-1) {fprintf (stderr, "%s%s%d\n", Strerror (errno            ), __file__, __line__); Return-1; Inter-process sharing-read-only mode the business often encounters a scenario in which a process needs to load a configuration file, possibly 100K large, if more than one process on this machine loads the configuration file, such as 200 processes, the total memory cost is 20M. But this consumption of memory is a serious waste if there are more files or more processes.        The better solution is that a process is responsible for loading the configuration file into shared memory, and then all the processes that need it are simply using this shared memory. } if (Shmctl (Shmid, ipc_rmid, 0) = =-1) {fprintf (stderr, "%s%s%d\n", Strerror (errno), __            file__, __line__);        return-1; } return 0;}

#include the "shm_com.h"/* Producer program uses the same key values to obtain and connect to the same shared memory segment, and then prompts the user for some text. If the flag written_by_you is set, the producer knows that the consumption process has not finished reading the last data, so it continues to wait. When the other process clears the flag, the producer writes the new data and sets the flag. It also uses the string end to terminate and detach shared memory segments. Here are the synchronization flags provided by Written_by_you, which is a very inefficient busy wait (nonstop loop).    */int Main (int argc, char** argv) {int running = 1, shmid;    struct Shared_use_st *shared_stuff; if (Shmid = Shmget ((key_t) 8888, sizeof (struct shared_use_st), PERM)) = =-1) {fprintf (St            Derr, "%s%s%d\n", Strerror (errno), __file__, __line__);        return-1;             } if ((Shared_stuff = (struct Shared_use_st *) Shmat (shmid, 0, 0) = = (struct Shared_use_st *)-1) {            fprintf (stderr, "%s%s%d\n", Strerror (errno), __file__, __line__);        return-1;                    } while (running) {while (shared_stuff->written_by_you = = 1) {                Sleep (1);            } printf ("Enter sone text:"); memset (Shared_stufF->some_text, 0, sizeof (shared_stuff->some_text));            Fgets (Shared_stuff->some_text, TEXT_SZ, stdin);            Shared_stuff->written_by_you = 1;                if (strncmp (Shared_stuff->some_text, "End", 3) = = 0) {running = 0;  }} if (Shmdt (shared_stuff) = =-1) {fprintf (stderr, "%s%s%d\n", Strerror (errno            ), __file__, __line__);        return-1; } return 0;}

    • Inter-parent interprocess communication
Communication between parent and child processes can also use shared memory because the child processes and parent processes generated by the fork do not share the memory area. After the parent process starts, create a memory share, and then call Fork to create the child process. Finally, in the parent-child process to do memory mapping to achieve data sharing.
Example code:
#include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h > #define PERM S_IRUSR | S_IWUSR |    Ipc_creattypedef char * p_str;int main (int argc, char **argv) {int shmid;    pid_t pid;    P_str p_shmaddr, c_shmaddr; if (Shmid = Shmget (Ipc_private, 1024x768, PERM) = = =-1) {fprintf (stderr, "%s%s%d\n", strerror            (errno), __file__, __line__);        return-1;                if (PID = fork ()) = = 0) {if (c_shmaddr = Shmat (shmid, 0, 0)) = = (P_STR) (-1))                    {fprintf (stderr, "%s%s%d\n", Strerror (errno), __file__, __line__);                return-1;            } memset (c_shmaddr, ' + ', 1024);            stpcpy (c_shmaddr, "Hello");                if (SHMDT (c_shmaddr) = =-1){fprintf (stderr, "%s%s%d\n", Strerror (errno), __file__, __line__);                return-1;        } wait (NULL);                } else if (PID > 0) {sleep (2); if (p_shmaddr = Shmat (shmid, 0, 0)) = = (P_STR) (-1)) {fprintf (std                        Err, "%s%s%d\n", Strerror (errno), __file__, __line__);                    return-1;                } printf ("%s\n", p_shmaddr); if (SHMDT (p_shmaddr) = =-1) {fprintf (stderr, "%s%s%d\n", Strerror (er                        Rno), __file__, __line__);                    return-1; } if (Shmctl (Shmid, ipc_rmid, 0) = =-1) {fprintf (stderr,                        "%s%s%d\n", Strerror (errno), __file__, __line__);                    return-1; }                Exit (0);                } else {fprintf (stderr, "%s%s%d\n", Strerror (errno), __file__, __line__);            return-1; } return 0;}


    • Inter-process sharing-read-only mode
Business often encounter a scenario, the process needs to load a configuration file, the file may be 100K large, if more than one process on this machine to load this configuration file, such as there are 200 processes, then the total memory cost is 20M, but if the file more or more process number, This consumption of memory is a serious waste. The better solution is that a process is responsible for loading the configuration file into shared memory, and then all the processes that need it are simply using this shared memory.

code temporarily don't want to write ... Make up for it when you need it ...

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Shared memory of Linux process communication

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.