目录
一:信号
信号编写代码较麻烦,需要绑定,需要发送,还有信号冲突,信号屏蔽的处理,最后还只能传递一个int数据类型的数据,如果从传递数据的角度上来看
信号是非常不合适的!
关于IPC技术之信号的学习,博主整理了不少出文章,可以学习
二:管道
管道分为匿名管道和有名管道两种
操作方向类似文件IO的操作方式
关于IPC技术之管道的学习,博主做出了整理,可以学习
管道能不能传递结构体?
可以!
查看write函数说明
因为 管道操作就是使用write和read
可以查看一下write函数第二个参数 是 void *(可以操作任何数据类型的数据)相比于信号(只能传递int数据类型的数据),而管道什么样的数据类型的数据都可以传递,相比信号优势更大
管道相比信号有优势,但是管道本身也是存在问题的
比如有名管道有时候会出现用户操作时误删管道文件
下面用一些例子,看一看管道的弊端
做个测试:只写不读,所有的数据都在管道中
#include<iostream>
#include <sys/types.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
int fdarr[2] = { 0 };//负责 父到子 传递
char buf[2] = { "a" };//使用固定数据 长度设置2
char resbuf[50] = { 0 };
pid_t pid = 0;
if (pipe(fdarr) != 0 )//只开一个管道
{
perror("pipe error");
}
else
{
pid = fork();
if (pid > 0)
{
//管道的读端关闭,执行写
close(fdarr[0]);
int count = 0;
while (1)
{
int wres = write(fdarr[1], buf, sizeof(buf));
//cout << "pid = " << getpid() << "通过管道发送数据" << endl;
count += wres;
cout << "count = " << count << endl;
bzero(buf, sizeof(buf));
}
}
else if(pid == 0)
{
//管道的写端关闭,执行读
close(fdarr[1]);
while (1)
{
/*int res = read(fdarr[0], resbuf, sizeof(resbuf));
cout << "pid = " << getpid() << "从管道读取数据 res = " << res << "resbuf = " << resbuf << endl;
bzero(resbuf, sizeof(resbuf));*/
}
}
}
return 0;
}
编译运行
g++ main.cpp -o main
./main
从结果不难看出,只写不读,那么在管道中的数据很快就写满
说明 整个管道最大能够容纳的数据量是65535【0-65535】
65535/1024 = 64 KB 如果管道中数据量超过64KB,会出现积压甚至溢出
说明了管道虽然可以传递多种数据类型的数据,但是容纳数据量有上限
管道对于发送一次就立马读一次,使用上没有什么问题。但是对于读很慢甚至是不读【例如上面代码示例是不读】,那数据一旦积压管道中,达到64KB,管道就不能使用了
【管道存在上限】【数组也有上限】【我们在存储数据中一般采用的是容器】【容器可扩大】
另外,管道不是一端启动就能使用,管道必须两端同时启动的时候,才可以使用
【管道要求两个进程同时操作才能使用】
三:消息队列 & 共享内存
消息队列和共享内存 在IPC通信中比较重要
消息队列在通知事件和数据传输具有极大优势,共享内存在共享数据方面具有极大优势,若是二者联合,就可以有效解决进程间通信的问题
【学习新技术,就好比我们在学习了容器后,就不会怎么去使用数组;
同样,学习消息队列和共享内存后,也不会怎么使用信号和管道】
关于IPC技术之消息队列与共享内存的学习,博主做出了整理,可以学习
四:进程间通信
进程间通信有如下一些目的:
数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间
共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)
资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变
信号:通知事件(信号处理函数) 数据传输(只能int)
管道:数据传输
消息队列:通知事件(效率最高) 数据传递
共享内存:共享数据 数据传输(效率最高)
以上都是可以实现进程间通信 数据传输的
五:IPC技术深度解析
IPC技术之间对比优缺点
1.信号:
优势:可以做到简单的(int)数据进程通信,可以做到进程通知效果
缺点:信号冲突 信号屏蔽
2.管道
优势:数据可以像文件IO操作类似,数据可以有很多类型
缺点:管道数据的承载有上限,命名管道文件会被误删
3.消息队列
优势:消息有顺序,读取的时候就会自动删除
缺点:和管道类似,数据有上限(系统全体队列、队列结构体固定)
4.共享内存
优势:传递数据的效率最高,数据没有类型限制
缺点:内存中是否有数据无法直观地看见,memcpy是非阻塞的,造成多进程或者多线程操作的时候会存在有数据的不安全问题