目录
IPC 进程间通信
进程间通信(Inter-Process Communication,简称 IPC)是指在不同进程之间进行数据交换、消息传递和资源共享的机制。
常见的 IPC 方式包括:
1. 管道(Pipe):分为无名管道和有名管道。无名管道只能在具有亲缘关系的进程间使用,而有名管道可在无亲缘关系的进程间通信。
2. 消息队列(Message Queue):消息的链表,存放在内核中并由消息队列标识符标识。
3. 共享内存(Shared Memory):多个进程可以访问同一块物理内存区域,实现快速的数据交换,但需要同步机制来协调访问。
4. 信号量(Semaphore):用于实现进程间的互斥与同步。
5. 套接字(Socket):可用于不同主机上的进程间通信,也可用于同一主机上的进程间通信。
进程间通信在多进程和多线程编程中起着至关重要的作用,使得不同的进程能够协同工作,完成复杂的任务。
1.管道通信
管道的特性
管道具有以下特性:
1. 半双工通信:数据只能在一个方向上流动。如果要实现双向通信,需要建立两个管道。
2. 只能在具有亲缘关系(如父子进程)的进程间使用:通常是父进程创建管道,然后创建子进程,子进程会继承父进程的文件描述符,从而实现通过管道通信。
3. 数据是字节流形式:管道中的数据没有固定的格式或消息边界,就像一个连续的字节流。
4. 管道的容量有限:通常是一个有限的缓冲区大小,如果写入的数据超过了缓冲区的容量,写进程会被阻塞,直到读进程读取数据腾出空间。64k
5. 管道是基于文件描述符的:通过对文件描述符进行读写操作来实现数据的传递。
6. 生命周期随进程:如果参与通信的进程结束,管道也会被销毁。
7.管道破裂,读端关闭,写管道。
使用流程
无名管道
创建管道-读写管道-关闭管道
1.创建并打开管道:
pipe函数
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建并打开一个无名管道
参数:pipefd[0] ==>无名管道的固定读端
pipefd[1] ==>无名管道的固定写端
返回值:成功 0
失败 -1;
注意事项:
1、无名管道的架设应该在fork之前进行。
2.无名管道的读写:
===》文件IO的读写方式。
读: read()
写: write()
3.关闭管道: close();
4.使用例子:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> /* Obtain O_* constant definitions */
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int pipefd[2]={0};
int ret = pipe(pipefd);
if(-1 == ret)
{
perror("pipe");
return 1;
}
pid_t pid = fork();
if(pid>0)
{
close(pipefd[0]);
sleep(3);
char buf[50]="hello,child";
write(pipefd[1],buf,strlen(buf));
}
else if(0 == pid)
{
close(pipefd[1]);
char buf[50]={0};
read(pipefd[0],buf,sizeof(buf));
printf("father :%s\n",buf);
}
else
{
perror("fork");
return 1;
}
return 0;
}
有名管道
有名管道===》fifo ==》有文件名称的管道。
文件系统中可见
框架:
创建有名管道 ==》打开有名管道 ==》读写管道
==》关闭管道 ==》卸载有名管道
1、创建:mkfifo
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:在指定的pathname路径+名称下创建一个权限为
mode的有名管道文件。
参数:pathname要创建的有名管道路径+名称
mode 8进制文件权限。
返回值:成功 0
失败 -1;
2、打开有名管道 open
注意:该函数使用的时候要注意打开方式,
因为管道是半双工模式,所有打开方式直接决定
当前进程的读写方式。
一般只有如下方式:
int fd-read = open("./fifo",O_RDONLY); ==>fd 是固定读端
int fd-write = open("./fifo",O_WRONLY); ==>fd 是固定写端
不能是 O_RDWR 方式打开文件。
不能有 O_CREAT 选项,因为创建管道有指定的mkfifo函数
3、管道的读写: 文件IO
读: read(fd-read,buff,sizeof(buff));
写: write(fd-write,buff,sizeof(buff));
4、关闭管道:
close(fd);
5、卸载管道:remove();
int unlink(const char *pathname);
功能:将指定的pathname管道文件卸载,同时
从文件系统中删除。
参数: ptahtname 要卸载的有名管道
返回值:成功 0
失败 -1;