管道是linux中程序間通訊的一種方式,它把乙個程序的輸出直接連線另乙個管道的輸入。linux的管道包括兩種:無名管道和有名管道。
特點:
只能用於具有親緣關係的程序間通訊(及父子或者兄弟程序)。
是一種單工的通訊模式,具有固定的讀端和寫端。
管道也可以看成一種特殊的檔案進行操作,對於它的讀寫也可以使用普通的read(),write()等函式。但是它不屬於任何檔案系統,並且只存在於核心中。
資料的讀出和寫入:乙個程序向管道中寫的內容被管道另一端的程序讀出。寫入的內容每次都新增在管道緩衝區的末尾,並且每次都是從緩衝區的頭部讀出資料。
注意:
只有在管道的讀端存在時,向管道寫入資料才有意義,否則,向管道寫資料的程序將收到核心傳來的sigpipe訊號(通常broken pipe錯誤)。
向管道寫入資料時,linux將不具有原子性,管道緩衝區只要有空間,寫程序就試圖向管道寫資料。如果管道緩衝區已滿,那麼寫操作將會一直阻塞。
父程序在執行時,它們的先後次序並不能保證。為了確保父程序已經關閉了相應的檔案描述符,可在兩個程序中呼叫sleep()函式。
管道建立函式:
所需標頭檔案: #include
函式原型: int pipe(int fd);
引數:fd:大小為2的整形陣列,用於存放管道的檔案描述符。
返回值:成功:0 錯誤:-1;
例項:
#include#include#include#include#include#include#includeint main(int arg,char *argv)
;//無名管道的套接的描符存放位址
char buf[1024];
if(pipe(fdpi)==-1)
pid_t pid=fork();
if(pid==-1)
else if(pid==0)
if(strcmp("eof",buf)==0)
}printf("chid:%d is quit\n",getpid());
} else
if(strcmp("eof",buf)==0)
else
}close(fdpi[0]);
close(fdpi[1]);
int cpid=wait(null);
printf("my child: %d is quit\n",cpid);
} return 0;
}
特點:
它可以使互不相關的兩個程序實現彼此通訊。
該管道可以通過路徑名來指出,並且在檔案系統中是可以見的。在建立管道之後,兩個程序就可以把它當作普通檔案進行讀寫操作,使用非常方便。
fifo嚴格地遵循先進先出規則,對管道及fifo的讀總是從開始處返回資料,對它們的寫規則把資料新增到末尾。有名管道不支援如lseek()等檔案定位操作。
注意:當乙個程序有名管道建立成功後有一直阻塞在**等待另乙個程序使用這個管道。
函式:
標頭檔案:#include#include
原型函式:int mkfifo(const char* filename,mode_t mode)
引數:filename: 管道名稱 mode:管道的訪問許可權
返回值:成功 0 失敗 -1
錯誤資訊:
eaccess 引數pathname所指定的目錄路徑無可執行的許可權
eexist 引數pathname所指定的檔案已存在。
enametoolong 引數pathname的路徑名稱太長。
enoent 引數pathname包含的目錄不存在
enospc 檔案系統的剩餘空間不足
enotdir 引數pathname路徑中的目錄存在但卻非真正的目錄。
erofs 引數pathname指定的檔案存在於唯讀檔案系統內。
例項
makefile:
source = $(wildcard *.c)
targets = $(patsubst %.c, %, $(source))
cc = gcc
cflags = -wall -g
all:$(targets)
$(targets):%:%.c
$(cc) $< $(cflags) -o $@
.phony:clean all
clean:
-rm -rf $(targets)
head:
#ifndef a_h
#define a_h
#include#include#include#include#include#include#include#include#include#define exit_fallure -1
#define max_masg 1024
#define fiof_c "fiof_c"
#define fiof_s "fiof_s"
#endif
server:
#include"./head.h"
int main(int argc,char *argv)
} if((send_fd=open(fiof_s,o_wronly))==-1)//開啟寫管道
if((recv_fd=open(fiof_c,o_rdonly))==-1)//開啟讀管道
puts("#######################");
while(1)
if(strcmp(send_buf,"quit")==0)
if(read(recv_fd,recv_buf,sizeof(recv_buf))==-1)
printf("client say is-->:%s\n",recv_buf);
if(strcmp(recv_buf,"quit")==0)
}close(send_fd);
close(recv_fd);
unlink(fiof_s);
return 0;
}
client:
#include"./head.h"
int main(int argc,char *argv)
} puts("#######################");
if((recv_fd=open(fiof_s,o_rdonly))==-1)//開啟讀管道
if((send_fd=open(fiof_c,o_wronly))==-1)//開啟寫管道
while(1)
printf("serv say is-->:%s\n",recv_buf);
if(strcmp(recv_buf,"quit")==0)
printf("clinet ->:");
bzero(send_buf,sizeof(send_buf));
fgets(send_buf,sizeof(send_buf),stdin);
send_buf[strlen(send_buf)-1]=0;
if(write(send_fd,send_buf,strlen(send_buf)+1)==-1)
if(strcmp(send_buf,"quit")==0)
}close(send_fd);
close(recv_fd);
unlink(fiof_c);
return 0;
}
程序間通訊 有名管道 無名管道
顧名思義,管道就像是將資料放入到乙個長長的管子中一樣,肯定會有一端寫入資料,稱為寫端,有一段讀出資料,稱為讀端。既然是說像管子一樣那麼它肯定有大小吧,資源不是無窮無盡的,預設下管道的大小是64k,用ulimit a 可以檢視。1 無名管道 管道是半雙工的,資料只能向乙個方向流動 需要雙方通訊時,需要...
C 程序間通訊 有名管道,無名管道
1 管道的概念 管道是單向的 先進先出 的,它把乙個程序的輸出和另乙個程序的輸入連線在一起。乙個程序 寫程序 在管道的 尾部寫入 資料,另乙個程序 讀程序 從管道的 頭部讀出 資料。資料被乙個程序讀出後,將被從管道中刪除,其它讀程序將不能再讀到這些資料。管道提供了簡單的流控制機制,程序試圖讀空管道時...
程序間通訊 無名管道
在上次的部落格中,我給大家介紹了程序間通訊的方式 有名管道。管道分為有名管道和無名管道,那麼此次我將給大家介紹一下另一種管道通訊 無名管道。有名管道是可以應用於任何兩個程序之間資料的單向傳遞,而無名管道是相對於有名管道的,無名管道在使用時產生,不使用後釋放,並不會在系統上留下任何痕跡。無名管道因其使...