一文学会Linux IPC通信
创始人
2024-05-08 00:03:29
0

目录

概览

单工、半双工、双工

各种IPC通信方式优缺点

1. 管道

2. 消息队列

3. 共享内存

4. 信号量

5. 信号

6. Socket套接字

精筛优秀博客


原本想详细写下,后发现有很多人总结过,那我就直接战在巨人的肩膀上不再重复造轮子了。

概览

单工、半双工、双工

  • 单工:单向通信
  • 半双工:双向通信,但不能同时双向
  • 全双工:双向通信,可同时双向

各种IPC通信方式优缺点

1. 管道

分为匿名管道和命名管道,都是半双工。

匿名管道只能亲缘关系的进程间使用(父子进程)。

#include 
int pipe(int fd[2]);    // 返回值:若成功返回0,失败返回-1

命名管道(又叫FIFO)本质是文件,可以非亲缘关系的进程间使用。

#include 
// 返回值:成功返回0,出错返回-1
int mkfifo(const char *pathname, mode_t mode);

不管是匿名管道还是命名管道,都是:先进先出,效率低,不适合频繁交换数据。 

2. 消息队列

#include 
// 创建或打开消息队列:成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);
// send:成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag);
// receive:成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
// control:成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

不一定要先进先出,可以用type控制。消息队列里有消息体,消息体被读取后删除,但消息队列生命周期跟随内核,进程销毁仍存在。

效率较高

不适合比较大的数据,在 Linux 内核中,会有两个宏定义 MSGMAX 和 MSGMNB,它们以字节为单位,分别定义了一条消息的最大长度和一个队列的最大长度。

存在用户态与内核态间数据拷贝开销

3. 共享内存

#include 
// 创建或获取一个共享内存:成功返回共享内存ID,失败返回-1
int shmget(key_t key, size_t size, int flag);
// 连接共享内存到当前进程的地址空间:成功返回指向共享内存的指针,失败返回-1
void *shmat(int shm_id, const void *addr, int flag);
// 断开与共享内存的连接:成功返回0,失败返回-1
int shmdt(void *addr); 
// 控制共享内存的相关信息:成功返回0,失败返回-1
int shmctl(int shm_id, int cmd, struct shmid_ds *buf);

两个进程虚拟地址映射到相同的物理地址。

效率最高,无用户态与内核态间数据拷贝开销

但无同步机制

4. 信号量

#include 
// 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1
int semget(key_t key, int num_sems, int sem_flags);
// 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops);  
// 控制信号量的相关信息
int semctl(int semid, int sem_num, int cmd, ...);

信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。若要进程间传递数据要配合共享内存

信号量初始化为1。P(通过)操作-1,V(释放)操作+1,信号量>=0进程才可继续执行。信号量<0进程阻塞等待其他进程把信号量恢复。

具体的过程如下:

  • 进程 A 在访问共享内存前,先执行了 P 操作,由于信号量的初始值为 1,故在进程 A 执行 P 操作后信号量变为 0,表示共享资源可用,于是进程 A 就可以访问共享内存。
  • 若此时,进程 B 也想访问共享内存,执行了 P 操作,结果信号量变为了 -1,这就意味着临界资源已被占用,因此进程 B 被阻塞。
  • 直到进程 A 访问完共享内存,才会执行 V 操作,使得信号量恢复为 0,接着就会唤醒阻塞中的线程 B,使得进程 B 可以访问共享内存,最后完成共享内存的访问后,执行 V 操作,使信号量恢复到初始值 1。

5. 信号

信号是进程间通信机制中唯一的异步通信机制。对于异常情况下的工作模式,就需要用「信号」的方式来通知进程。

在 Linux 操作系统中, 为了响应各种各样的事件,提供了几十种信号,分别代表不同的意义。我们可以通过 kill -l 命令,查看所有的信号:

$ kill -l1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

6. Socket套接字

可以跨网络与不同主机的进程间通信,也可以同主机通信。本地字节流 socket 和 本地数据报 socket 在 bind 的时候,不像 TCP 和 UDP 要绑定 IP 地址和端口,而是绑定一个本地文件,这也就是它们之间的最大区别。

根据创建 socket 类型的不同,通信的方式也就不同:

  • 实现 TCP 字节流通信: socket 类型是 AF_INET 和 SOCK_STREAM;
  • 实现 UDP 数据报通信:socket 类型是 AF_INET 和 SOCK_DGRAM;
  • 实现本地进程间通信: 「本地字节流 socket 」类型是 AF_LOCAL 和 SOCK_STREAM,「本地数据报 socket 」类型是 AF_LOCAL 和 SOCK_DGRAM。另外,AF_UNIX 和 AF_LOCAL 是等价的,所以 AF_UNIX 也属于本地 socket;

各种通信方式的比较和优缺点

  1. 管道:速度慢,容量有限,只有父子进程能通讯

  2. FIFO:任何进程间都能通讯,但速度慢

  3. 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题

  4. 信号量:不能传递复杂消息,只能用来同步

  5. 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

如想看具体实现看下面链接。

精筛优秀博客

进程间通信——几种方式的比较和详细实例_worthsen的博客-CSDN博客_进程间的通信方式三种

5.2 进程间有哪些通信方式? | 小林coding (xiaolincoding.com)

Linux c/c++之IPC进程间通信_石小浪♪的博客-CSDN博客_ipc_set

Linux进程间通信的几种方式总结--linux内核剖析(七)-阿里云开发者社区 (aliyun.com)

相关内容

热门资讯

安卓系统8.0镜像下载,轻松打... 你有没有想过,想要给你的安卓手机升级到最新的系统,却不知道从哪里下载那个神秘的安卓系统8.0镜像呢?...
安卓系统修改大全,全方位修改大... 你有没有想过,你的安卓手机其实是个大宝藏,里面藏着无数可以让你手机焕然一新的秘密?没错,今天就要来个...
安卓刷miui系统教程,安卓刷... 你有没有想过给你的安卓手机换换口味?别看它现在用得挺顺手的,偶尔来点新鲜感也是不错的。今天,就让我来...
超星学系统安卓版,便捷学习新体... 你有没有发现,学习生活越来越离不开电子设备了?手机、平板,这些小玩意儿简直就是我们的学习小助手。今天...
安卓平板6.0系统安装,轻松上... 你有没有想过,你的安卓平板6.0系统是不是该升级一下了呢?别看它现在看起来还挺精神的,但谁知道背后隐...
安卓系统屏幕显示文字,探索个性... 你有没有发现,手机屏幕上的文字有时候会变得模糊不清,或者颜色暗淡,让人看得很费劲?这可真是让人头疼的...
快递扫描系统下载安卓,便捷物流... 你有没有想过,每次快递员来送快递,他们是怎么快速找到你的包裹的呢?是不是觉得他们有超能力?其实,这背...
安卓系统能打开zip,操作指南... 你有没有想过,你的安卓手机里那些神秘的zip文件到底怎么打开呢?别急,今天就来给你揭秘这个小小的技术...
塞班怎么查找安卓系统,塞班系统... 你有没有想过,你的塞班手机里竟然也能装上安卓系统?听起来是不是有点神奇?别急,今天我就来手把手教你如...
安卓系统短消息提醒,安卓系统短... 你有没有发现,手机里的短消息提醒功能有时候就像一个贴心的管家,有时候又像个爱闹腾的小孩子?今天,咱们...
安卓系统如何跳过密码,安卓系统... 你是不是也和我一样,有时候手机锁屏密码设置得太复杂,每次解锁都要费好大一番力气?别急,今天就来教你怎...
鸿蒙系统功能与安卓,功能对比与... 你知道吗?最近手机圈里可是热闹非凡呢!华为的新操作系统鸿蒙系统(HarmonyOS)一经推出,就引发...
安卓系统卡苹果系统不卡,揭秘两... 你有没有发现,身边的朋友都在争论安卓系统和苹果系统哪个更好?其实,这个问题就像是在问谁家的孩子更聪明...
安卓系统卡解决了吗,安卓系统卡... 你有没有遇到过安卓手机卡顿的问题?是不是每次打开应用都感觉像蜗牛爬行?别急,今天就来聊聊这个让人头疼...
华为安卓系统下载软件,畅享海量... 你有没有想过,手机里的系统就像是我们的大脑,而下载的软件就像是大脑里的各种功能?今天,就让我带你一起...
平板安卓7系统好吗,体验流畅与... 你有没有想过,你的平板电脑的安卓7系统到底怎么样呢?是不是觉得它既熟悉又有点陌生?别急,今天咱们就来...
鸿蒙系统和安卓10,跨时代操作... 你知道吗?最近科技圈可是炸开了锅,因为华为的新操作系统鸿蒙系统横空出世,而且它竟然和安卓10杠上了!...
苹果安卓和鸿蒙系统,三大操作系... 你有没有发现,现在的手机市场就像是一场精彩纷呈的武林大会,各路英雄齐聚一堂,各显神通?没错,说的就是...
鸿蒙怎么还原安卓系统,系统还原... 你是不是也和我一样,对鸿蒙系统里的安卓应用情有独钟呢?最近,不少小伙伴都在问,鸿蒙怎么还原安卓系统?...
荣耀10改回安卓系统,重拾纯净... 你有没有想过,你的荣耀10手机,曾经那般风光无限,如今却想要改回安卓系统呢?这可不是一件小事,得好好...