Linux interprocess communication-Shared memory

Source: Internet
Author: User
Tags readable semaphore



A shared memory introduction shared memory can be literally understood,share a piece of logical memory, let different processes access it, modify it。 Shared memory is a very efficient way to share and pass data between two running processes. Memory that is shared between different processes is usually scheduled as the same piece of physical memory. Processes can connect the same piece of shared memory to their own address space, and all processes can access the addresses in the shared memory as if they were allocated by the C-language function malloc. If a process writes data to shared memory, the changes will immediately affect any other process that can access the same piece of shared memory. But one thing's special to note: Shared memory does not provide a synchronization mechanism. That is, there is no automatic mechanism to prevent the second process from starting to read the shared memory until the first process ends the write operation on it. Thewe usually need to use other mechanisms to synchronize access to shared memory, such as semaphores. Two shared memory uses create shared memory int shmget (key_t key, size_t size, int shmflg); ◇ first parameter, name of Shared memory segment, Shmget function returns a shared memory identifier (non-negative integer) associated with key when successful. Used for subsequent shared memory functions. The call failed to return-1. ☆ Other processes can access the same shared memory through the return value of the function, which represents a resource that the process may want to use, and the program accesses all shared memory indirectly, first by calling the Shmget function and providing a key. A corresponding shared memory identifier (the return value of the Shmget function) is generated by the system, and only the Shmget function uses the semaphore key directly, and all other semaphore functions use the semaphore identifier returned by the Semget function. ◇ the second parameter, size specifies the amount of memory that needs to be shared in bytes. ◇ The third parameter, SHMFLG is a permission flag, and its function is the same as the Open function's mode parameter, if you want the key to identify the shared memory does not exist, it can be done with ipc_creat or operation. The permission flags for shared memory are the same as the read and write permissions for a file, for example, 0644, which means that shared memory that is allowed to be created by a process is read and written to shared memory by processes owned by the memory creator, while processes created by other users can read only shared memory. Start access to the shared memory void *shmat (int shm_id, const void *shm_addr, int shmflg); ◇ The first time the shared memory is created, it cannot be accessed by any process. The purpose of the Shmat function is to initiate access to the shared memory and connect the shared memory to the address space of the current process. ◇ The first parameter, shm_id is the shared memory ID returned by the Shmget function. ◇ The second parameter, SHM_ADDR specifies that the shared memory is connected to the address location in the current process, which is usually empty, indicating that the system chooses the address of the shared memory. ◇ The third parameter, SHM_FLG is a set of flag bits, usually 0. ◇ When the call succeeds, returns a pointer to the first byte of shared memory if the call fails to return-1. Separates the shared memory from the current process int shmdt (const void *SHMADDR); ◇ This function is used to detach shared memory from the current process. Note that separating shared memory is not removing it, just making that shared memory no longer available to the current process. ◇ parameter shmaddr is the address pointer returned by the SHMAT function, returns 0 upon successful invocation, and 1 on failure. Control shared memory int shmctl (int shm_id, int command, struct SHMid_ds *buf); ◇ first argument, shm_id is the shared memory identifier returned by the Shmget function. ◇ the second parameter, command is the action to take, it can take the following three values: Ipc_stat: Set the data in the SHMID_DS structure to the current associated value of shared memory, that is, the value of Shmid_ds is overwritten with the current associated value of shared memory. Ipc_set: If the process has sufficient permissions, set the current association value for shared memory to the value given in the SHMID_DS structure Ipc_rmid: Delete shared memory segment ◇ The third parameter, buf is a struct pointer that points to the structure of shared memory mode and access rights. struct shmid_ds{uid_t shm_perm.uid;uid_t shm_perm.gid;mode_t Shm_perm.mode;} Three examples shmdata.h source code: #ifndef _shmdata_h_ Header#define _shmdata_h_header#define TEXT_SZ 2048struct shared_use_st{int written;/* as a flag, non 0: readable, 0 means writable */char text[text_sz];/* record the text written and read */}; #endif shmread.c source #include <unistd.h> #include <stdlib.h> #include < stdio.h> #include <sys/shm.h> #include "shmdata.h" #define MEM_KEY (1234) int main () {int running = 1;// Whether the program continues to run flag Void*shm = NULL; The original first address of the allocated shared memory struct Shared_use_st *shared;//points to shmint Shmid; Shared memory identifier//create shared memory Shmid = Shmget ((key_t) mem_key,sizeof (struct shared_use_st), 0666| Ipc_creat); if (Shmid ==-1) {fprintf (stderr, "Shmget failed\n"); exit (exit_failure);} Connect shared memory to the address space of the current process SHM = Shmat (shmid,0,0)if (SHM = = (void*)-1) {fprintf (stderr, "Shmat failed\n"); exit (exit_failure);} printf ("\nmemory attached at%x\n", (int) SHM);//set shared memory shared = (struct shared_use_st*) Shm;shared->written =0;while ( Running)//read the data in shared memory {//No process to the shared memory fixed data has data readable if (Shared->written!=0) {printf ("you wrote:%s", shared->text); sleep (rand ()%3);//After reading the data, set written to make the shared memory segment writable Shared->written =0;//Enter end, exit the Loop (program) if (strncmp (Shared->text, "End", 3) = =0) running = 0;} else//There are other processes in writing data that cannot read data sleep (1);} Detach the shared memory from the current process if (SHMDT (SHM) ==-1) {fprintf (stderr, "Shmdt failed\n"); exit (exit_failure);} Delete Shared memory if (Shmctl (Shmid, ipc_rmid,0) ==-1) {fprintf (stderr, "Shmctl (ipc_rmid) failed\n"); exit (exit_failure);} Exit (exit_success);} SHMWRITE.C source code #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h># include<sys/shm.h> #include "shmdata.h" #define MEM_KEY (1234) int main () {int running =1;VOID*SHM = null;struct Shared_use_st *shared = Null;char buffer[bufsiz +1];//is used to save input text int shmid;//Create shared memory Shmid = Shmget ((key_t) mem_key,sizeof (struct shared_use_st), 0666| Ipc_creat); if (Shmid ==-1) {fprintf (stderr, "Shmget failed\n"); exit (exit_failure);} Connect the shared memory to the current process's address space SHM = Shmat (Shmid, (void*) 0,0), if (SHM = = (void*)-1) {fprintf (stderr, "Shmat failed\n"); Exit (Exit_ FAILURE);} printf ("Memory attached at%x\n", (int) SHM);//set shared memory shared = (struct shared_use_st*) shm;while (running)//write data to Shared memory {// The data has not been read, wait for the data to be read, cannot write to the shared memory while (Shared->written ==1) {sleep (1);p rintf ("waiting...\n");} Writes data to the shared memory printf ("Enter some text:"); fgets (buffer, bufsiz, stdin); strncpy (shared->text, buffer, TEXT_SZ);//finish writing the data , set written to make the shared memory segment readable Shared->written =1;//enter end, exit the Loop (program) if (strncmp (buffer, "End", 3) ==0) running = 0;} Detach the shared memory from the current process if (SHMDT (SHM) ==-1) {fprintf (stderr, "Shmdt failed\n"); exit (exit_failure);} Sleep (2); exit (exit_success);} Code Analysis: ◇ program Shmread Create shared memory, and then connect it to your own address space. A structure Struct_use_st was used at the beginning of shared memory. There is a flag in this structure written, when other processes in the shared memory write to it, the written in shared memory is set to 0, and the program waits. When it is not 0 o'clock, indicating that no process is writing data to the shared memory, the program reads the data from the shared memory and outputs it, then resets the written in shared memory to 0, which allows it to be written to by the shmwrite process. ◇ ChengThe shmwrite obtains shared memory and connects to its own address space. Check if the written in shared memory is 0, if not, indicates that the data in shared memory has not been completed, waits for the other process to read, and prompts the user to wait. If the shared memory written is 0, indicating that no other process is reading the shared memory, prompting the user for text, and setting the written in shared memory again to 1, indicating that the write is complete and that other processes can read the shared memory. Security discussion on the previous exampleThis program is not safe,Problems occur when multiple programs are reading and writing data to shared memory at the same time. You might think that you can change the way written is used, for example, only if the written is 0 o'clock the process can write data to the shared memory, and when a process is written not 0 o'clock to read it, and the written is added 1 operation, After reading, the operation is reduced by 1. This is a bit like the ability to read and write locks in file locks. Look, it seems to make sense.. But this is not an atomic operation, so this practice is not possible. Imagine that when written is 0 o'clock, if there are two processes accessing shared memory at the same time, they will find that written is 0, so two processes write to it, obviously not. When written is 1 o'clock, there are two processes concurrently reading the shared memory, and when both processes are read, written becomes-1. To make the program safe to perform, there is a process synchronization of the system, to ensure that the operation into the critical section is atomic operation. For example, you can use the semaphore described earlier to synchronize processes. Because the operation of the semaphore is atomic. 3 Advantages and disadvantages of using shared memory ◇ Advantage: we can see that using shared memory for inter-process communication is really very convenient, and the interface of the function is also simple, the data sharing also makes the data between processes do not transfer, but direct access to memory, but also speed up the efficiency of the program. At the same time, it does not require a certain parent-child relationship as the process of communicating with anonymous pipelines. ◇ Cons: Shared memory does not provide a mechanism for synchronization, which allows us to use shared memory for inter-process communication, often using other means to synchronize processes. Four better examples 1, server.c/*server.c: Write to Shared memory people*/#include <stdio.h> #include <sys/types.h> #include <sys/ ipc.h> #include <sys/sem.h> #include <string.h> #include "credis.h" int semid;int shmid;/* Semaphore p operation */void p () {struct SEMBUF sem_p;sem_p.sem_num=0;/* set which semaphore */sem_p.sem_op=-1;/* define Operation */if (Semop (semid,&sem_p,1) ==-1)   printf ("P operation is fail\n"); the/*SEMOP function automatically executes an array of operations on the semaphore set.   int semop (int semid, struct sembuf semoparray[], size_t nops); Semoparray is a pointer to an array of semaphore operations. NOPS Specifies the number of operations in the array. V Operation of */}/* Semaphore */void V () {struct Sembuf sem_v;sem_v.sem_num=0;sem_v.sem_op=1;if (semop (semid,&sem_v,1) ==-1) printf ("V operation is fail\n");} int main () {Structpeople{char name[10];int age;}; key_t semkey;key_t Shmkey;semkey=ftok (".. /TEST/VENUSDB.CBP ", 0);//used to produce a unique marker for distinguishing the semaphore and shared memory shMkey=ftok (".. /test/main.c ", 0);/* Create xsi Ipc*/semid=semget of semaphores (semkey,1,0666| Ipc_creat);//Parameter Nsems, at this time the median value 1, specifies the number of semaphore sets containing the semaphore//0666| Ipc_creat is used to indicate read/write access to the semaphore/* from left to right: first bit: 0 indicates that this is a 8 binary number second bit: The current user's permissions: 6=110 (binary), each bit is readable, writable, executable, 6 indicates that the current user can read writable non-executable third: Group users, 6 of the meaning of the fourth bit: other users, each of the meaning of the same, 0 means unreadable and non-writable can not execute */if (semid==-1) printf ("Creat sem is fail\n");//Create Shared memory Shmid=shmget ( shmkey,1024,0666| Ipc_creat);//For Shared memory if (shmid==-1) printf ("Creat shm is fail\n");/* Sets the initial value of the semaphore, which is the number of resources */union Semun{int val;struct Semid_ds *buf;unsignedshort*array;} sem_u;sem_u.val=1;/* Set Variable value */semctl (Semid,0,setval,sem_u);//initializes the semaphore, sets the No. 0 semaphore, and P () operates as a non-blocking /* Maps the shared memory to the address of the current process, and then directly to the address in the process addr operation is to the shared memory Operation */structpeople*addr;addr= (structpeople*) Shmat (shmid,0,0); Map shared memory to the memory segment that calls this function if (addr== (structpeople*)-1) printf ("Shm Shmat is fail\n"),/* writes data to shared memory */p (); strcpy ((*addr). Name, " Xiaoming ");/* Note: ① can only assign values directly to the address pointed to by the pointer, and cannot define a struct people people_1;addr=&people_1; because addr is in addr= (struct people*) Shmat (shmid,0,0), when an address has been automatically assigned by the system, this address is associated with shared memory, so you cannot change the pointer's direction, otherwise he will not point to shared memory and cannot complete the communication. Note: ② assigns a value to a character array. It was just a tiger. */(*ADDR). AGE=10;V ()/* Disconnect the shared memory from the current process */if (SHMDT (addr) ==-1) printf ("Shmdt is fail\n");} 2. CLINET.C/*CLIENT.C: read out people*/#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h from shared memory > #include <sys/sem.h>int semid;int shmid;/* signal Volume P operation */void p () {struct SEMBUF sem_p;sem_p.sem_num=0;sem_p.sem_ Op=-1;if (Semop (semid,&sem_p,1) ==-1) printf ("P operation is fail\n");} /* Semaphore v Operation */void V () {struct Sembuf sem_v;sem_v.sem_num=0;sem_v.sem_op=1;if (semop (semid,&sem_v,1) ==-1) printf ("V Operation is fail\n ");} int main () {key_t semkey;key_t Shmkey;semkey=ftok (".. /tEST/CLIENT/VENUSDB.CBP ", 0); Shmkey=ftok (". /test/client/main.c ", 0); Structpeople{char name[10];int age;};/ * Read shared memory and Semaphore Ipc*/semid=semget (semkey,0,0666), if (semid==-1) printf ("Creat sem is fail\n"); Shmid=shmget (Shmkey, 0,0666), if (shmid==-1) printf ("Creat shm is fail\n"),/* Maps shared memory to the address of the current process, and then directly to the address in the process addr operation is for shared memory operations */structpeople* Addr;addr= (structpeople*) Shmat (shmid,0,0), if (addr== (structpeople*)-1) printf ("Shm Shmat is fail\n");/* Read data from shared memory */p ();p rintf ("name:%s\n", Addr->name);p rintf ("age:%d\n", Addr->age), V ();/* Disconnects shared memory from the current process */if (SHMDT (addr) ==-1) printf ("Shmdt is fail\n");/*ipc must show delete. Otherwise it will remain present in the system */if (Semctl (semid,0,ipc_rmid,0) ==-1) printf ("Semctl delete error\n"); if (Shmctl (shmid,ipc_rmid,null) ==- 1) printf ("Shmctl delete error\n");} Five parent-child process shared memory sub #include<stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h > #define Shm_key 0x33#define sem_key 0x44union semun {int val;struct semid_ds *buf;unsignedshort*array;}; int P (int semid) {struct SEMBUF sb;sb.sem_num =0;sb.sem_op =-1;SB.SEM_FLG = sem_undo;if (Semop (semid,&sb,1) ==-1) {perror ("Semop"); return-1;} Return0;} int V (int semid) {struct Sembuf sb;sb.sem_num =0;sb.sem_op =1;sb.sem_flg = sem_undo;if (Semop (semid,&sb,1) ==-1) { Perror ("Semop"); return-1;} Return0;} int main (int argc,char**argv) {pid_t pid;int I, Shmid, semid;int*ptr;union semun semopts;/* Create a piece of shared memory, save an int variable */if (shmid = Shmget (shm_key,sizeof (int), ipc_creat |0600)) (==-1) {perror ("Msgget");} /* Maps shared memory to a process, after which the child process can inherit the mapping */if ((ptr = (int*) shmat (Shmid, null,0)) = = (void*)-1) {perror ("Shmat");} *ptr =0;/* creates a semaphore used to synchronize shared memory Operations */if ((Semid = Semget (sem_key,1, Ipc_creat |0600)) ==-1) {perror ("Semget");} /* Initialize semaphore */semopts.val =1;if (Semctl (semid,0, Setval, semopts) <0) {perror ("Semctl");} if (PID = fork ()) <0) {perror ("fork");} ElseIf (PID ==0) {/* Child *//* Sub-process to shared memory plus 1 */for (i =0; I <100; i++) {P (semid);(*ptr) + +; V (Semid);p rintf ("Child:%d\n", *ptr);}} else{/* *//* Parent process to shared memory minus 1 */for (i =0; I <100; i++) {P (semid);(*ptr)--; V (Semid);p rintf ("Parent:%d\n", *PTR);} Waitpid (PID); sleep (2);/* If the synchronization succeeds, the shared memory value is 0 */printf ("Finally:%d\n", *ptr);} Return0;}

  

Linux interprocess communication-Shared memory

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.