目录
进程间通信(IPC)操作系统为用户提供的几种用于进程间通信的方式(管道,共享内存,消息队列,信号量)
目的:进程具有独立性(每个进程都有自己的虚拟地址空间,访问的都是自己的虚拟地址,其他进程在自己的虚拟地址空间映射中实际上是没有这个数据的),因此进程间无法直接通信,但是在大型项目中多个协同工作很常见,这时候进程间通信就尤为重要.
进程间通信根据不同的实际应用场景来采用不同的方式.
一.管道-PIPE
半双工通信:管道有两端,但是数据从哪端到哪端这个由用户来定
1.管道的分类
1.1匿名管道
内核中开辟的一块缓冲区,没有标识符,无法被其他进程找到(只能用于具有亲缘关系的进程间通信)
例如:一个进程通过系统调用在内核创建了一个匿名管道,为了能够让用户操作这个管道,因此调用了文件描述符作为这个管道的操作句柄,其它进程因为这个管道没有标识符,找不到因此无法通信.但是,如果这个创建管道的进程创建了一个子进程,这时候子进程复制了父进程(文件描述符表),所以子进程相当于也有文件描述符可以操作这个管道.
只有通过子进程复制父进程的方式才能获取到同一个管道的操作句柄.
int main(){
//匿名管道只能用于具有亲缘关系的进程间通信,子进程复制父进程的方式获取操作句柄
//注意:创建管道一定要放在创建子进程之前
int pipefd[2];
int ret=pipe(pipefd);
if(ret<0){
perror("pipe error");
return -1;
}
pid_t pid =fork();
if(pid<0)
{
perror("fork error");
return -1;
}
if(pid==0){
//子进程向管道写数据
char*str="一天课,难受~! \n";
write(pipefd[1],str,strlen(str));
}
else
{
//父进程从管道读数据
char buf[1024]={0};
read(pipefd[0],buf,1023);
printf("read:%s",buf);
}
close(pipefd[0]);
close(pipefd[1]);
return 0;
}
1.2命名管道
内核中开辟的一块缓冲区,具有标识符,可以被其他进程找到
命名管道:一个进程创建一个命名管道,这个命名管道会在文件系统中创建出一个管道文件(可以看得到的,实际上就是管道的名字),多个进程通过打开同一个管道文件,访问内核中的同一个缓冲区实现通信,可以用于同一主机上的任意进程间通信.
操作:mkfifo 文件创建命名管道文件
接口:int mkfifo(char *filename,mode_t mode);
以p开头的是管道文件,创建命名管道文件,并不会立即创建内核中的
2.管道的本质和特性
2.1本质
内核中的一块缓