关于C语⾔中进程通信的5种⽅式Unix/Linux系统中C语⾔进程通信的5种⽅式
进程通信
操作系统中每个进程地址空间相互独⽴,进程间通信必须经过内核。
⼴义进程通信⽅式
1. ⽂件
2. 管道
3. 内存映射
4. 共享内存
5. 信号
6. 套接字
7. 消息队列
8. 剪切板
9. 远程过程调⽤
单机环境中常见的进程通信⽅式
管道通信
管道通信也成为匿名管道。管道通信使⽤⽅式最简单,⽤于有⾎缘关系的进程间通信。
主要特点:
使⽤两个⽂件描述符,⼀端表⽰读,⼀端表⽰写
两个进程都终结管道才终结
读端以及写端默认是阻塞的
本质是⼀个内核缓冲区,使⽤循环队列实现,
不可反复读取
函数原型:
/**
* 参数:
*  数组中[0]、[1]分别代表读端和写端
* 返回值:
*  成功返回0
*  失败返回-1,并设置errno值
*/
int pipe(int[2]);
命名管道
区别于管道通信,命名管道(FIFO)可以进⾏没有关联的进程间通信。
主要特点:
FIFO是Unix/Linux基础⽂件类型的⼀种,⽂件类型⽤p标识
FIFO在⽂件磁盘上数据快⼤⼩为0,仅⽤来标识内核中的通道
使⽤⽅式:
1. 创建管道⽂件
管道⽂件严格遵循先进先出的⽅式,读取从开始处返回数据,写⼊将数据添加到末尾。
使⽤命令创建管道⽂件
mkfifo管道名
函数创建
/**
*参数:
*  1:⽂件名
*  2:权限
* 返回值:
*  ⽂件描述符
*/
int mkfifo(const char*, mode_t);
2. 操作⽂件
管道⽂件与普通⽂件使⽤⽅式相同,系统的⽂件操作函数都可⽤于管道⽂件。
内存映射
存储映射是使磁盘中的⽂件与内存中的缓冲区相映射。
在缓冲区中读取数据,相当于读取⽂件中的数据;将数据写⼊缓冲区,相当于写⼊⽂件。
这样就可以只使⽤指针来完成I/O操作,可以⽤于⽆关联的进程之间的通信。
使⽤⽅式:
1. 打开⽂件
2. 函数调⽤
/**
* 参数:
*  1:映射起始地址,⼀般设置NULL,由操作系统指定
*  2:映射长度
*  3:读写模式
*  4:写⼊映射区是否写⼊到⽂件中(MAP_ANONYMOUS匿名映射)
*  5:步骤1中打开的⽂件描述符(当⽂件描述符为-1使⽤匿名映射)
*  6:⽂件偏移长度
* 返回:
*  映射区⾸地址(内存块,与数组相似)
*/
void*mmap(void*, size_t,int,int,int, off_t)
3. 释放资源
/**
* 参数:
*  1:地址
*  2:映射长度
*  返回值:
*  成功返回0
*  失败返回-1
*/
int munmap(void*, size_t)
信号
信号是信息的载体。当⼀个进程收到信号后,暂停运⾏,去执⾏信号处理函数,类似于中断。
信号的三种状态:
产⽣
信号的产⽣包含按键、系统调⽤、软件条件、异常以及命令等⽅式。
未决
产⽣和递达之间的状态,主要由于阻塞或者屏蔽产⽣。
递达
送达到进程中。
使⽤⽅式:
1. 信号处理函数
/**
* 信号处理函数
* 函数名⾃定义
*/
void handle(int)
2. 注册信号处理函数
⽅式⼀
/**
* signal函数参数:
*  1:信号编号
*  2:信号处理函数
*/
void(*signal(int,void(*)(int)))(int);
⽅式⼆
/**
* sigaction函数参数:
*  1:信号编号
*  2:传⼊参数:新的信号处理⽅式
*  3:传出参数:旧的信号处理⽅式
* 返回值:
*  是否成功
*/
int sigaction(int,const struct sigaction * __restrict,
struct sigaction * __restrict);
合理使⽤信号阻塞能够解决进程间的同步问题。
共享内存
共享内存的实质是将内核的⼀块内存映射到进程中,操作本地的内存相当与操作共享内存,⽤于⽆关联的进程之间。使⽤⽅式:
1. 创建共享内存
/**
* 函数参数:
*  1:共享内存唯⼀key
*  2:共享内存⼤⼩
*  3:创建模式以及权限
* 返回值:
*  成功:返回共享内存ID(与key不⼀定相同)
*  失败:返回-1
*/
int shmget(key_t, size_t,int);
2. 关联共享内存
/
**
* 函数参数:
*  1:共享内存ID
*  2:设置当前进程中的内存地址(与共享内存地址不⼀定相同),⼀般为NULL  *  3:读写模式
* 返回值:
*  成功:当前内存地址
*  失败:返回-1(void *)
*/
void*shmat(int,const void*,int);
3. 读写内存
与数组操作基本⼀致,操作共享内存地址。
4. 断开共享内存
/**
* 函数参数:
*  当前进程相关联的内存地址进程通信方式
* 返回值:
*  成功与否
*/
int shmdt(const void*);
5. 删除共享内存
/**
* 函数参数:
*  1:共享内存ID
*  2:操作(获取状态信息、设置信息、删除)
*  3:内容
* 返回值:
*  成功与否
*/
int shmctl(int,int,struct shmid_ds *)
此⽂档只作抛砖引⽟,详细原理仍需要深⼊研究。