当前位置: 首页> 文旅> 酒店 > 【回眸】Linux内核(十一) 进程间通讯 之 管道

【回眸】Linux内核(十一) 进程间通讯 之 管道

时间:2025/8/27 14:23:30来源:https://blog.csdn.net/tianbutian_/article/details/139493887 浏览次数:0次

前言

进程的介绍已经告一段落,接下来学习的内容是进程间的通讯.

进程间通信(IPC)

面试考点:

IPC的通讯方式通常有:管道(无名和命名) ,消息队列,信号量,共享存储,socket,streams等.socket和streams支持2个不同的主机上的2个进程IPC.

管道通常指无名管道

特点:

1. 半双工(只能在一个方向上流动)

2. 只能用于具有亲缘关系的进程间通讯(父子进程or兄弟进程)

3.读写可用 read write 等函数,不属于其他任何文件系统,只存在于内存中.

局限性:

1. 同一时间只能单向(eg:父进程读,子进程写);

2. 管道数据,读完就没啦

函数原型:
#include <unistd.h>
int pipe(int fd[i]); //成功返回值为0,失败返回值为1
fd[0]为读而打开 ------>关闭--------> close fd[0]
fd[1]为写而打开 ------>关闭--------> close fd[1]

无名管道函数应用:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (){int fd[2];int pid ;char buf[128];if (pipe(fd) == -1){printf("create pipe failed!\n");}pid = fork();if (pid < 0){printf ("create child progress failed!\n");}else if(pid > 0){printf("this is father progress!\n");close(fd[0]);write(fd[1],"hello from father",strlen("hello from father"));wait(&pid);}else{printf("this is child progress!\n");close(fd[1]);read(fd[0],buf,128);printf("read from father:%s!\n",buf);exit(0);}return 0;
}
运行结果参考图:

命名管道(FIFO)

FIFO也称命名管道,是一种文件类型.

特点

1. FIFO 可以在无关的进程之间交换数据,与无名管道不同.

2. FIFO 有路径名与之相关连,它以一种特殊的设备文件形式存在与文件系统中.

函数原型
#include <sys/stat.h>
int mkfifo(const char* pathname,moode_t mode);
//成功返回值为0,失败返回值为-1
命名管道以文件的形式存储在磁盘,所以在创建FIFO之后可以用一般的I/O函数操作它.

一般read之后都会阻塞,等读取到write内容后才会回复正常.

也可以设置成非阻塞,但是不经常用于FIFO.

 有名管道函数应用:

comm3.c

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>int main(){
if (mkfifo("./file",0600) == -1 && errno!= EEXIST)
{printf("mkfifo failed \n");perror("why");
}
int fd =open ("./file",O_RDONLY);
printf ("open successfully!\n ");
return 0;
}

comm4.c

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>int main(){int fd =open ("./file",O_WRONLY);
printf ("write open successfully!\n ");
return 0;
}

运行编译命令及运行结果参考:

 命名管道(持续收发版)

comm5.c(read)

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h> int main(){char buf[30] = {0};int nread = 0;if (mkfifo("./file",0600) == -1 && errno!= EEXIST)
{printf("mkfifo failed \n");perror("why");
}
int fd =open ("./file",O_RDONLY);
printf ("open successfully!\n ");
while(1){
nread = read(fd,buf,30);
printf("Read %d byte from fifo,context = %s \n",nread,buf);
}
close(fd);
return 0;
}

 comm6.c(write)

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h> int main(){int cnt = 0;char *str = "message from fifo.";int fd =open ("./file",O_WRONLY);printf ("write open successfully!\n ");while(1){write(fd,str,strlen(str));sleep(1);cnt = cnt + 1;if (cnt == 5){break;}}close(fd);return 0;
}

 运行编译命令及运行结果参考:

上述代码是写5遍,写完后不停读取,读完之后就读不到内容了.

关键字:【回眸】Linux内核(十一) 进程间通讯 之 管道

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: