Table of Contents
1. Shared memory
Apply for shared memory shmget
Control shared memory shmctl
Associative shared memory shmat / Deassociated shared memory shmdt
2. Message queue
Create or open a message queue msgget
send message msgsnd / receive message msgrcv
Control message msgctl
3. Semaphore
Create or open a semaphore semget
Semaphore operation semop
Semaphore control semctl
One, shared memory
Shared memory is the fastest form of inter-process communication IPC, which allows two or more processes to share the same area of physical memory (usually called a segment), and inter-process data transfer will no longer involve the kernel (that is, it will no longer pass kernel system calls to pass data);
Maintain shared memory data structures
//vim /usr/include/bits/shm.h struct shmid_ds { struct ipc_perm shm_perm; /* operation perms */ int shm_segsz; /* size of segment (bytes) */ __kernel_time_t shm_atime; /* last attach time */ __kernel_time_t shm_dtime; /* last detach time */ __kernel_time_t shm_ctime; /* last change time */ __kernel_ipc_pid_t shm_cpid; /* pid of creator */ __kernel_ipc_pid_t shm_lpid; /* pid of last operator */ unsigned short shm_nattch; /* no. of current attaches */ unsigned short shm_unused; /* compatibility */ void *shm_unused2; /* ditto - used by DIPC */ void *shm_unused3; /* unused */ };
//vim /usr/include/bits/ipc.h /* Data structure used to pass permission information to IPC operations. */ struct ipc_perm { __key_t __key; /* Key. */ __uid_t uid; /* Owner's user ID. */ __gid_t gid; /* Owner's group ID. */ __uid_t cuid; /* Creator's user ID. */ __gid_t cgid; /* Creator's group ID. */ unsigned short int mode; /* Read/write permission. */ unsigned short int __pad1; unsigned short int __seq; /* Sequence number. */ unsigned short int __pad2; __syscall_ulong_t __unused1; __syscall_ulong_t __unused2; };
Apply for shared memory shmget
- key, used to uniquely distinguish shared memory, can be generated by the ftok function;
- size, it is recommended to be a multiple of 4KB;
- shmflg, label;
- IPC_CREAT, if the target shared memory does not exist, create it, otherwise obtain it;
- IPC_CREAT | IPC_EXCL, if the target shared memory does not exist, create it, otherwise an error occurs;
//vim /usr/include/bits/ipc.h #include <bits/types.h> /* Mode bits for `msgget', `semget', and `shmget'. */ #define IPC_CREAT 01000 /* Create key if key does not exist. */ #define IPC_EXCL 02000 /* Fail if key exists. */ #define IPC_NOWAIT 04000 /* Return error on wait. */ /* Control commands for `msgctl', `semctl', and `shmctl'. */ #define IPC_RMID 0 /* Remove identifier. */ #define IPC_SET 1 /* Set `ipc_perm' options. */ #define IPC_STAT 2 /* Get `ipc_perm' options. */ #ifdef __USE_GNU # define IPC_INFO 3 /* See ipcs. */ #endif
Control shared memory shmctl
Associated shared memory shmat / delinked shared memory shmdt
//makefile CC=gcc .PHONY:all all: server client server:server.c $(CC) -o $@ $^ client:client.c $(CC) -o $@ $^ .PHONY:clean clean: rm -rf server client//comm.h #pragma once #include <stdio.h> #define PATH_NAME "/home/wz/Desktop/pipe" #define PROJ_ID 0x6666 #define SIZE 4097//server.c include "comm.h" #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { key_t k = ftok(PATH_NAME, PROJ_ID); if(k < 0){ perror("ftok"); return 1; } printf("key: %x\ ", k); sleep(3); int shmid = shmget(k, SIZE, IPC_CREAT|IPC_EXCL|0644); if(shmid < 0){ perror("shmget"); return 2; } printf("shmid: %d\ ", shmid); sleep(3); char* start = (char*)shmat(shmid, NULL, 0); printf("server already attach on shared memory!\ "); while(1){ printf("%s\ ", start); sleep(1); if(strlen(start) == 26) break; } shmdt(start); printf("server already dattach off shared memory!\ "); sleep(3); shmctl(shmid, IPC_RMID, NULL); printf("delete %d\ ", shmid); return 0; }//client.c #include "comm.h" #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { key_t k = ftok(PATH_NAME, PROJ_ID); if(k < 0){ perror("ftok"); return 1; } printf("key: %x\ ", k); sleep(3); int shmid = shmget(k, SIZE, IPC_CREAT); if(shmid < 0){ perror("shmget"); return 2; } printf("client shmid: %d\ ", shmid); sleep(3); char* start = (char*)shmat(shmid, NULL, 0); printf("client already attach on shared memory!\ "); char c = 'A'; while(c <= 'Z'){ start[c - 'A'] = c; c++; sleep(1); } shmdt(start); printf("client already dattach off shared memory!\ "); sleep(3); return 0; }
//View shared memory [wz@192 pipe]$ ipcs -m //Delete shared memory with specified id [wz@192 pipe]$ ipcrm -m 426047
The life cycle of shared memory depends on the OS;
Shared memory does not provide any synchronization or mutual exclusion and is independent of each other;
Shared memory is the fastest among all inter-process communications;
The shm allocated by the shared memory system is based on 4KB as the basic unit. If you specify something other than a multiple of 4KB, the excess will be wasted;
Two, message queue
Message queue is a method of inter-process communication, providing a way to send a piece of data from one process to another process;
Maintain message queue data structures
//vim /usr/include/bits/msq.h /* Structure of record for one message inside the kernel. The type `struct msg' is opaque. */ struct msqid_ds { E> struct ipc_perm msg_perm; /* structure describing operation permission */ __time_t msg_stime; /* time of last msgsnd command */ #ifndef __x86_64__ unsigned long int __unused1; #endif __time_t msg_rtime; /* time of last msgrcv command */ #ifndef __x86_64__ unsigned long int __unused2; #endif __time_t msg_ctime; /* time of last change */ #ifndef __x86_64__ unsigned long int __unused3; #endif __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ __syscall_ulong_t __unused4; __syscall_ulong_t __unused5; };
Create or open message queue msgget
- key, used to uniquely distinguish shared memory, can be generated by the ftok function;
- msgflg,label;
- IPC_CREAT, if the target message queue does not exist, create it, otherwise obtain it;
- IPC_CREAT | IPC_EXCL, if the target message queue does not exist, create it, otherwise an error occurs;
send message msgsnd / receive message msgrcv
Control message msgctl
Three, semaphore
The semaphore is not originally used to transmit data between processes, it is used as the original synchronization process, mainly used for synchronization and mutual exclusion; because the process requires shared resources, some resources need to be mutually exclusive; some resources in the system are only allowed to be used at one time A process uses these resources as critical resources or mutually exclusive resources; a program segment involving mutually exclusive resources is called a critical section;
Maintain the semaphore data structure
//vim /usr/include/bits/sem.h /* Data structure describing a set of semaphores. */ struct semid_ds { struct ipc_perm sem_perm; /* operation permission struct */ __time_t sem_otime; /* last semop() time */ __syscall_ulong_t __unused1; __time_t sem_ctime; /* last time changed by semctl() */ __syscall_ulong_t __unused2; __syscall_ulong_t sem_nsems; /* number of semaphores in set */ __syscall_ulong_t __unused3; __syscall_ulong_t__unused4; };
create or open semaphore semget
semaphore operation semop
semaphore control semctl