Message Queuing is used to implement the FIFO of the message, but it is faster to use shared memory for the FIFO of the message;
We first complete the C language version of Shmfifo (based on the procedure call), and then implement the C + + version of Shmfifo on this basis, will be 1 blocks of shared memory with 3 semaphores (1 mutext semaphores, 1 full semaphores, 1 empty semaphores) Encapsulated into a class Shmfifo, and then write their own test code;
Shmfifo Description:
The requested shared memory is used as a buffer, and the header (P_shm to P_payload) of the memory is formatted as shown in the form;
Read/write process constantly in accordance with the principle of cash first out of the read/write data from it, the read/write process can be regarded as producer/consumer, therefore, using the semaphore Sem_mutex (initial value of 1) to mutually exclusive access to shared memory, using Sem_full (initial value is the number of shared buffer blocks), sem_ Empty (initial value is 0) to synchronize two processes.
We use C + + to achieve:
Shmfifo class Design class Shmfifo {public : shmfifo (int _key, int _blksize, int _blocks); ~shmfifo (); void put (const void *buf); void get (void *buf); void Destroy (); Private: typedef struct SHMHEAD { unsigned int blksize; Block size unsigned int blocks; Total block number unsigned int rd_index; Read index block unsigned int wr_index; Write index block } shmhead_t; Private: shmhead_t *p_shm; Shared memory head pointer char *p_payload; Payload in fact address int shmid; Shared memory ID int Sem_mutex; Mutex semaphore int sem_full; Full semaphore int sem_empty; Empty signal volume };
/** constructor **/shmfifo::shmfifo (int _key, int _blksize, int _blocks) {//Open a piece of shared memory Shmid = Shmget (_key, 0, 0); If the open fails, the shared memory is not created, then the IF (Shmid = =-1) {/** Sets the shared memory **/int size = _blksize*_block s + sizeof (shmhead_t); Create shared memory Shmid = Shmget (_key, size, ipc_creat|0666); if (Shmid = =-1) err_exit ("Shmget error"); To create the shared memory successfully, you need to connect it to the process's address space P_SHM = (shmhead_t *) Shmat (shmid, NULL, 0); if (P_shm = = (void *)-1) err_exit ("Shmat error"); Initializes the header of the shared memory to a struct shmhead p_shm->blksize = _blksize; P_shm->blocks = _blocks; P_shm->rd_index = 0; P_shm->wr_index = 0; P_payload = (char *) (P_SHM+1); /** set three semaphores **/Sem_mutex = sem_create (_key); Sem_setval (Sem_mutex, 1); Sem_full = Sem_create (_key+1); Sem_setval (Sem_full, _blocks); Sem_empty = SEM_create (_key+2); Sem_setval (sem_empty, 0); } else {//shared memory already exists and opened successfully, you only need to connect it to the process's address space P_SHM = (shmhead_t *) Shmat (shmid, NULL, 0); if (P_shm = = (void *)-1) err_exit ("Shmat error"); P_payload = (char *) (P_SHM+1); /** Open three semaphores **/Sem_mutex = Sem_open (_key); Sem_full = Sem_open (_key+1); Sem_empty = Sem_open (_key+2); }}/** destructor **/Shmfifo::~shmfifo () {SHMDT (P_SHM); Unmount shared Memory P_shm = NULL; P_payload = NULL; }
/** destroy function **/ void Shmfifo::d Estroy () { sem_delete (Sem_mutex); Sem_delete (sem_full); Sem_delete (sem_empty); if (Shmctl (Shmid, Ipc_rmid, NULL) = =-1) err_exit ("Remove share memory Error"); }
/** put function **/ void Shmfifo::p ut (const void *buf) { sem_p (sem_full); Sem_p (Sem_mutex); /** enters the critical section **/ //Gets the write position from the structure char *index = p_payload + (P_shm->wr_index * p_shm->blksize); Write memcpy (index, buf, p_shm->blksize); Index shift P_shm->wr_index = (p_shm->wr_index+1)%p_shm->blocks; /** exit Critical Zone **/ Sem_v (Sem_mutex); Sem_v (Sem_empty); }
/** get function **/ void shmfifo::get (void *buf) { sem_p (sem_empty); Sem_p (Sem_mutex); /** enters the critical section **/ //obtains the readout position from the structure char *index = p_payload + (P_shm->rd_index * p_shm->blksize); Read memcpy (buf, index, p_shm->blksize); P_shm->rd_index = (p_shm->rd_index+1)%p_shm->blocks; /** exit Critical Zone **/ Sem_v (Sem_mutex); Sem_v (Sem_full); }
. Phony:clean all CC = g++ cppflags =-wall-g bin = Write Read free SOURCES = $ (bin.=.cpp) All : $ (BIN) %.O:%.cpp $ (cc) $ (cppflags)-C $^-o [email protected] WRITE:WRITE.O shmfifo.o IPC.O $ (cc) $ (cppflags) $^-lrt-o [email protected] READ:READ.O shmfifo.o ipc.o $ (CC) $ (cppflags) $^-lrt-o [email protected] FR EE:FREE.O shmfifo.o ipc.o $ (CC) $ (cppflags) $^-lrt-o [email protected] Clean : -rm-rf $ (BIN) *.O Bin/ob J/core
Need real-time link library, only need to modify the makefile file, plus-LRT can be
Linux interprocess communication (IPC) programming Practice (11) System v Semaphore---Implement a first in, out shared memory Shmfifo