进程间通信的本质就是让不同的进程看到同一份资源,也就是同一块内存

进程间通信的目的

* 数据传输
* 资源共享
* 通知事件
* 进程控制
进程通信分离

* 管道
* 匿名管道pipe
* 命名管道
* System V IPC
* 消息队列
* 共享内存
* 信号量
* POSIX IPC
* 消息队列
* 共享内存
* 信号量
* 互斥量
* 条件变量
* 读写锁

管道

管道都是单向传输内容的 

匿名管道

父进程写入,子进程读
#include <unistd.h> int pipe(int fd[2]); // 创建一个无名管道,fd[0]表示读端,fd[1]表示写端 //
成功返回0,失败返回错误代码
父进程创建管道,然后fork出子进程,父进程关闭fd[0],子进程关闭fd[1]。

管道的特点:

* 管道是用来进行具有血缘关系的进程进行进程间通信
* 管道具有通过进程间协同,提供了访问控制
* 管道提供的是面向流的通信服务
* 管道是基于文件的,文件的生命周期是随进程的,管道的生命周期也是随进程的
* 管道是单向通信
访问控制:

* 写快读慢,写满了就不能再写
* 写慢读块,管道没有数据的时候,读需要等待
* 写关,没有读,就读到文件结尾
* 读关,写继续,OS终止写进程
例子:从键盘读取数据,写入管道,读取管道,写到屏幕
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
int main( void ) { int fds[2]; char buf[100]; int len; if ( pipe(fds) == -1 )
perror("make pipe"),exit(1); // read from stdin while ( fgets(buf, 100, stdin)
) { len = strlen(buf); // write into pipe if ( write(fds[1], buf, len) != len )
{ perror("write to pipe"); break; } memset(buf, 0x00, sizeof(buf)); // read
from pipe if ( (len=read(fds[0], buf, 100)) == -1 ) { perror("read from pipe");
break; } // write to stdout if ( write(1, buf, len) != len ) { perror("write to
stdout"); break; } } }
命名管道

在不相关的进程之间交换数据,可以使用FIFO文件。命名管道就是一种特殊的文件
// 创建命名管道 int main(int argc, char *argv[]) { mkfifo("p2", 0644); return 0; }
// 函数原型:int mkfifo(const char *filename,mode_t mode);
区别

唯一的区别就是在创建与打开的方式不同。命名管道由mkfifo创建,open打开;匿名管道由pipe创建并打开。

共享内存

 提供者是操作系统,共享内存=共享内存块+对应的共享内存的内核数据结构来管理

当进程结束时,共享内存块还在。system v的ipc资源,生命周期随内核,需要自己删除
ipcs -m // 查看共享内存 ipcrm -m id // 删除id的共享内存

共享是属于用户空间,就是不用经过系统调用,直接可以访问。双方进程如果想通信,直接机械能内存级的读写就可。共享内存是最快的,因为不需要拷贝,也就不用交给操作系统;但是缺乏访问控制,会带来并发问题。

信号量

让不同的进程看到了同一份资源,也带来了一些时序问题,造成数据不一致问题

临界资源:多个进程(执行流)看到的公共的一份资源

临界区:自己的进程,访问临界资源的代码

互斥:为了更好的进行临界区的保护,可以让多执行流在任何时刻都只能一个进程进入临界区

原子系:要么不做,要么做完,没有中间状态

所以多个执行流,运行的时候互相干扰,主要是我们不加保护的访问了同样的资源(临界资源),在非临界区多个执行流互相是不影响的

申请信号量的本质:让信号量计数器--,P操作,必须是原子的

申请信号量成功,临界资源内部,一定会给你预留你想要的资源,本质就是临界资源的一种预定机制。

释放信号量就是计数器++,V操作,必须是原子的

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信