Linux process synchronization exit problem with shared memory communication

Source: Internet
Author: User
Tags flock posix

Two or more processes use shared memory (SHM) to communicate, always experiencing synchronization problems. The "Synchronization problem" here is not that the process reads and writes the synchronization problem, this uses the semaphore to be good. The synchronization problem here is that the synchronous exit problem, in the end who quit first, how to know the other side quit. For example: process is responsible for reading and writing database A, process B is responsible for processing the data. Then process a can exit at a later date than process B, because the data that process B finishes with is saved. But a doesn't know when B quits. A, B is unrelated process, also do not know the other side of the PID. Their only association is to read and write the same piece of shared memory. Under normal circumstances, process B writes an identity in shared memory: Process a You can quit and you can. However, process B may be an abnormal exit, even if the identity is too late to write. Secondly, the shared memory used to do data communication, plus such a logo feeling is not very good, there is a feeling of abuse.

There is no problem with socket communication because the process B exit can also cause the socket to be disconnected, even if it is timed out. But SHM does not have an agreement to detect these behaviors, and it would be too much trouble to do it yourself. Let's start with shared memory.

Shared memory is managed by the kernel, and a process that deletes its own open shared memory does not affect the shared memory of another process, even if it is the same piece of shared memory. This is because a reference count in the kernel exists within the share, and a process that uses that shared memory causes the reference count to be added by 1. If one of the processes calls the Delete function, only this count is 0 to actually delete the shared memory. Then, the process that requires the last exit to detect this count is available.

In shared memory of System V, creating a shared memory Initializes a structure:

           structShmid_ds {structIpc_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*/               ...           };

You can read the struct by using the Shmctl function, where the shm_nattch is the number of processes that use that shared memory.

However, there is now a new POSIX standard, of course, to use the new standard. The shared memory created by Shm_open also has the "one process delete itself open shared memory that does not affect the shared memory of another process" feature. However, the shared memory created with Shm_open no longer has the above structure, so how does the kernel manage Shm_open create shared memory?? Look at the following source code:

/*shm_open-open A shared memory file*//*Copyright 2002, Red Hat INC.*/#include<sys/types.h>#include<sys/mman.h>#include<unistd.h>#include<string.h>#include<fcntl.h>#include<limits.h>intShm_open (Const Char*name,intOflag, mode_t mode) {  intFD; Charshm_name[path_max+ -] ="/dev/shm/"; /*Skip opening slash*/  if(*name = ='/')    ++name; /*Create special shared memory file name and leave enough space to cause a path/name error if name is too long */strlcpy (Shm_name+9, name, Path_max +Ten); FD=Open (Shm_name, oflag, mode); if(FD! =-1)    {      /*once open we must add fd_cloexec flag to file descriptor*/      intFlags = FCNTL (FD, F_GETFD,0); if(Flags >=0) {Flags|=fd_cloexec; Flags=fcntl (FD, F_SETFD, flags); }      /*On failure, just close file and give up*/      if(Flags = =-1) {close (FD); FD= -1; }    }  returnFD;}

I am, this is the creation of a normal file Ah, just create the location under/DEV/SHM (that is, RAM). Then take a look at the function Shm_unlink to delete shared memory:

/*shm_unlink-remove A shared memory file*//*Copyright 2002, Red Hat INC.*/#include<sys/types.h>#include<sys/mman.h>#include<unistd.h>#include<string.h>#include<limits.h>intShm_unlink (Const Char*name) {  intRC; Charshm_name[path_max+ -] ="/dev/shm/"; /*Skip opening slash*/  if(*name = ='/')    ++name; /*Create special shared memory file name and leave enough space to cause a path/name error if name is too long */strlcpy (Shm_name+9, name, Path_max +Ten); RC=unlink (shm_name); returnRC;}

This is just a normal unlink function. In other words, the POSIX standard shared memory is a file. The so-called "one process delete itself open shared memory does not affect the shared memory of another process" is equivalent to you open a file with the FStream object, and then go to the folder to delete the file (that is, the file unlink operation), but FStream object can also read and write files, And there's no reference count. Well, the process is out of sync again.

But how can there be problems that can't be solved under Linux? Can't solve can only explain oneself too dish. Since it's a file, start with the file. What is the atomic operation of the file and can be counted? Answer: Hard link. Like what:

[Email protected]:/dev/shm$StatABC file:"ABC"Size:4Block:8IO BLOCK:4096Normal file device: 15h/21D Inode:5743159Hard Links:1Permissions: (0664/-rw-rw-r--) Uid: ( +/XZC) Gid: ( +/Xzc) recently visited: -- on- -  +: -:00.961053098+0800Recent Changes: -- on- -  +: -:00.961053098+0800Recent Changes: -- on- -  +: -:00.961053098+0800creation Time:-[email protected]-hp-probook-4446s:/dev/shm$

This hard link can be obtained through the Fstat function. But to do so, it means creating a piece of shared memory, each of which needs to call the link function to create a hard link. The problem is solved, but this will be more than n multiple files under/DEV/SHM. This is Ram Ah, although the server is now compared to cattle, but this is not very good. OK, there is also a flock file lock. Flock uses the Lock_sh parameter to lock the same file with multiple processes. In this way, process B initializes the shared memory with a lock (which can have multiple processes) and is unlocked when exiting (including an exception exit). Process a detects this lock on exit. The description can be safely exited when no lock is found.

The problem of synchronous exit is basically solved. Too late to write code to verify, next time.

PS: Kernel unlink should also have a count to know that there is currently no process to open the file, when should delete the file. This also has to go to the data, see the use. In addition lsof This tool can detect all the processes that open the shared memory and the corresponding state. This should also have a corresponding API, but now still do not understand.

Linux process synchronization exit problem with shared memory 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.