目录
一,共享内存
申请共享内存 shmget
控制共享内存 shmctl
关联共享内存 shmat / 去联共享内存 shmdt
二,消息队列
创建或打开消息队列 msgget
发送消息 msgsnd / 接收消息 msgrcv
控制消息 msgctl
三,信号量
创建或打开信号量 semget
信号量操作 semop
信号量控制 semctl
一,共享内存
共享内存是最快的进程间通信IPC形式,即允许两个或多个进程共享物理内存的同一块区域(通常被称为段),进程间数据传递将不再涉及到内核(即将不再通过内核系统调用来传递数据);

维护共享内存的数据结构
//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;    
    }; 申请共享内存 shmget
- key,用于唯一区分共享内存,可由ftok函数生成;
- size,建议为4KB的倍数;
- shmflg,标签; 
  - IPC_CREAT,如目标共享内存不存在,即创建,否则获取;
- IPC_CREAT | IPC_EXCL,如目标共享内存不存在,即创建,否则出错;
 

//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 控制共享内存 shmctl

关联共享内存 shmat / 去联共享内存 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\n", k); sleep(3); int shmid = shmget(k, SIZE, IPC_CREAT|IPC_EXCL|0644); if(shmid < 0){ perror("shmget"); return 2; } printf("shmid: %d\n", shmid); sleep(3); char* start = (char*)shmat(shmid, NULL, 0); printf("server already attach on shared memory!\n"); while(1){ printf("%s\n", start); sleep(1); if(strlen(start) == 26) break; } shmdt(start); printf("server already dattach off shared memory!\n"); sleep(3); shmctl(shmid, IPC_RMID, NULL); printf("delete %d\n", 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\n", k); sleep(3); int shmid = shmget(k, SIZE, IPC_CREAT); if(shmid < 0){ perror("shmget"); return 2; } printf("client shmid: %d\n", shmid); sleep(3); char* start = (char*)shmat(shmid, NULL, 0); printf("client already attach on shared memory!\n"); char c = 'A'; while(c <= 'Z'){ start[c - 'A'] = c; c++; sleep(1); } shmdt(start); printf("client already dattach off shared memory!\n"); sleep(3); return 0; }
//查看共享内存 [wz@192 pipe]$ ipcs -m //删除指定id共享内存 [wz@192 pipe]$ ipcrm -m 426047
共享内存的生命周期随OS;
共享内存不提供任何同步与互斥,彼此独立;
共享内存是所有进程间通信中,速度最快的;
共享内存系统分配的shm,是按照4KB为基本单位的,如指定不是4KB的倍数,多余会浪费掉;
二,消息队列
消息队列是进程间通信的一种方式,提供一个从一个进程向另一个进程发生一块数据的方法;
维护消息队列的数据结构
//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;    
  }; 创建或打开消息队列 msgget
- key,用于唯一区分共享内存,可由ftok函数生成;
- msgflg,标签; 
  - IPC_CREAT,如目标消息队列不存在,即创建,否则获取;
- IPC_CREAT | IPC_EXCL,如目标消息队列不存在,即创建,否则出错;
 

发送消息 msgsnd / 接收消息 msgrcv

控制消息 msgctl

三,信号量
信号量并不是原来进程间传输数据的,是原来同步进程当作的,主要用于同步与互斥;由于进程要求共享资源,而有些资源需互斥使用;系统中的某些资源一次只允许一个进程使用,称这些资源为临界资源或互斥资源;涉及到互斥资源的程序段,称为临界区;
维护信号量的数据结构
//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;    
  };    
创建或打开信号量 semget

信号量操作 semop

信号量控制 semctl

![java八股文面试[java基础]——面相对象特点](https://img-blog.csdnimg.cn/18d323e4077d4fd9adb43dc12ee5d621.png)













![[MAUI]模仿网易云音乐黑胶唱片的交互实现](https://img-blog.csdnimg.cn/img_convert/9c786c58b312e861e47ead2241e04780.gif)




