Shared memory Basic Concepts
The shared memory area is the fastest IPC form . Once such memory is mapped to the address space of the process that shares it, these inter-process data transfers no longer involve the kernel, in other words, the process no longer passes the data () to each other by executing system calls into the kernel.
Shared Memory VS. Other IPC forms
Passing data with pipeline / Message Queuing
Passing data with shared memory
(The kernel maintains a data structure for each IPC object)
After the shared memory is generated, passing the data does not need to go to the Linux kernel , and shared memory allows two or more processes to share a given storage area , and the data does not need to be replicated between multiple processes , so Shared memory transfer speed faster!!
System v Shared memory data structure and basic API
Basic data structure struct shmid_ds{ struct ipc_perm shm_perm; /* Ownership and Permissions */ size_t shm_segsz; /* Size of Segment (bytes) */ time_t shm_atime; /* Last Attach time */ time_t shm_dtime; /* Last Detach time */ time_t shm_ctime; /* Last Change time */ pid_t shm_cpid; /* PID of Creator */ pid_t shm_lpid; /* PID of Last Shmat (2)/SHMDT (2) */ shmatt_t shm_nattch; /* No. of current attaches */ ...};
Shared Memory functions
#include <sys/ipc.h> #include <sys/shm.h>int shmget (key_t key, size_t size, int shmflg), void *shmat (int shmid , const void *shmaddr, int shmflg), int shmdt (const void *shmaddr), int shmctl (int shmid, int cmd, struct shmid_ds *buf);
Shmget function
Function: Create shared memory and initialize the contents of the memory to 0
Prototype:
int Shmget (key_t key, size_t size, int shmflg);
Parameters:
Key: This shared memory segment name
Size: Shared Memory sizes
SHMFLG: Consists of nine permission flags, and their usage is the same as the mode pattern flag used when creating the file.
return value:
A non-negative integer, the identifier of the shared memory segment, was successfully returned; 1 failure return
Experiment 1: Open the existing shared memory int main () {//int shmget (key_t key, size_t size, int shmflg); Open the already existing shared memory int shmid = Shmget (0x225,1024,0666); if (Shmid = =-1) { if (errno = = ENOENT) { cout << "ENOENT =" << errno << Endl; } err_exit ("Shmget error"); } return 0;}
Experiment 2: If the shared memory exists, it is used directly; if it does not exist, it is created. [ipc_creat option function]int Main () { //int shmget (key_t key, size_t size, int shmflg); int shmid = Shmget (0x225,1024,0666| Ipc_creat); if (Shmid = =-1) { if (errno = = ENOENT) { cout << "ENOENT =" << errno << endl;
} err_exit ("Shmget error"); } else { cout << "shmid =" << shmid << Endl; } return 0;}
Experiment 3: Shared memory is created if it is not, or an error is returned if it exists. [ipc_creat| IPC_EXCL Combination Action]int main () { //int shmget (key_t key, size_t size, int shmflg); int shmid = Shmget (0x225,1024,0666| Ipc_creat| IPC_EXCL); if (Shmid = =-1) { if (errno = = ENOENT) { cout << "ENOENT =" << errno << Endl; } else if (errno = = eexist) { cout << "File is exits ... Eexist = "<< errno << Endl; } Err_exit ("Shmget error"); } else { cout << "shmid =" << shmid << Endl; } return 0;}
Shmat function
Function: Connect shared memory segments to process address space
Prototype:
void *shmat (int shmid, const void *shmaddr, int shmflg);
Parameters:
Shmid: Shared Memory identity
SHMADDR: Specify the address of the connection
SHMFLG: Two of its possible values are shm_rnd and shm_rdonly
return value:
Successfully returns a pointer to the first section of shared memory; failure return-1
SHMADDR and SHMFLG combination description
Shmaddr is in Null,linux and will automatically connect to that memory for the process (recommended)
SHMADDR is not null and SHMFLG has no shm_rnd tag, the SHMADDR is the connection address.
SHMADDR is not null and SHMFLG sets the shm_rnd tag, the connected address is automatically adjusted downward to an integer multiple of Shmlba. Formula: shmaddr-(shmaddr% Shmlba)
shmflg=shm_rdonly, indicating that the connection operation is used for read-only shared memory
Example 1int Main () { //int shmget (key_t key, size_t size, int shmflg); Get or open shared memory int shmid = Shmget (0x1576422, sizeof (Student), 0666 | Ipc_creat); if (Shmid = =-1) { err_exit ("Shmget error"); } Connect the shared memory with ID Shmid to the process Student *pstudent = static_cast<student *> (Shmat (shmid, NULL, 0)); Write data to memory Student Studenta = {"Xiaofang", +}; memcpy (pstudent,&studenta,sizeof (Student)); cout << pstudent->name << "" << pstudent->number << Endl; can also get the memory content (in fact, there is no difference with local memory) Student *pnewstudent = pstudent; cout << pnewstudent, name <<, << pnewstudent, number << Endl; return 0;}
Example 2: Treat shared memory as an array int main () { //int shmget (key_t key, size_t size, int shmflg); Get or open shared memory int shmid = Shmget (0x15764221, 1024x768 * sizeof (int), 0666 | Ipc_creat); if (Shmid = =-1) { err_exit ("Shmget error"); } Connect the shared memory with ID Shmid to the process int *parray = Static_cast<int *> (Shmat (shmid, NULL, 0)); if (Parray = = (void *)-1) { err_exit ("Shmat error"); } for (int i = 0; I! = 1024x768; ++i) { parray[i] = i+1; } for (int i = 0; I! = 1024x768; ++i) { cout << parray[i] << Endl; } return 0;}
Linux Shared memory practices (1)