除了以上限制,管道还有一些其他的缺点,比如管道没有名字(匿名管道),管道的缓冲区大小是有限的。管道传输的是未格式化的字节流。这就需要管道的输入和输出事先约定好数据格式。虽然有这么多缺点,但是对于一些简单的进程间通信,管道还是完全可以胜任的。使用管道进行通信时,两端进程通过管道创建时系统设置的文件描述符向管道读写数据。管道本质上也是文件的一种,但它不同于普通的文件,它可以克服使用文件进行通信的两个问题。这个文件只存在于内存中。两个进程通过管道进行通信,一个进程向管道写入数据,另一个进程从中读取数据。每次写入的数据都添加到管道缓冲区的末尾,读取数据时从缓冲区的头部读取数据。#includeintpipe(intpipefd[2]);(匿名)管道的两端分别由描述符pipefd[0]和pipefd[1]描述。需要注意的是,管道两端的任务是固定的,一端只能用于读,用描述符pipefd[0]表示,称为管道的读端;另一端只能用于写,用描述符pipe[1]]表示,表示称为管道的写端。该函数创建的管道两端处于一个进程的中间,在实际应用中意义不大。所以,一个进程用pipe()创建管道后,一般会fork出一个子进程,然后通过管道实现父子进程。沟通。这里就不多介绍了,一起来看看著名的pipeline吧。管道的一个缺点是它没有名字,因此只能用于有亲和力的进程间通信。著名管道(namepipeorFIFO)提出后,解决了这个限制。FIFO和pipeline的区别在于,她提供了一个与之关联的路径名,以FIFO文件的形式存储在文件系统中。命名管道是一个设备文件,因此进程可以通过FIFO相互通信,即使它们与创建FIFO的进程没有关联,只要它们可以访问路径。值得注意的是,FIFO(FirstInFirstOut)始终按照先进先出的原则工作,先写入的数据先从管道中读出。在Linux中我们经常使用管道来重定向数据。例如:下面介绍创建知名管道的系统调用,有两个,mknod和mkfifo模式);functionmknod参数中,pathname为创建知名管道的全路径名,mode为创建知名管道的模式,表示其访问权限;dev是一个设备值,它取决于文件创建的类型,只有在创建一个设备文件时才会用到。这两个函数调用成功返回0,否则返回-1。读写众所周知的管道:#includessize_tread(intfd,void*buf,size_tnbytes)ssize_twrite(intfd,void*buf,size_tnbytes)然后给出让我们演示一个通过众所周知的通道进行通信的聊天程序...点击(这里)折叠或打开//Lisi.c#include#include#include#include#include#include#include#include#defineFIFO_READ"writefifo"//另一个程序只要把这个程序#defineFIFO_WRITE"readfifo"//复制一份,替换这两个宏#defineBUF_SIZE1024intleft=0;void*read_buf(){intrfd=-1;charbuf[BUF_SIZE]={'\0'};inti;printf("等待对方...\n");while((rfd=open(FIFO_READ,O_RDONLY))==-1){sleep(1);}while(left!=1){//printf("i=%d",i++);intlen=read(rfd,buf,BUF_SIZE);if(len>0){buf[len]='\0';if(strcmp(buf,"不理你")==0){printf("\n对方已经消失了!\n");left=1;break;//exit(0);}for(i=0;i
