管道是進程通信的手段之一,管道實際上只存在內存的文件,對這個文件的操作是通過兩個打開的文件描述符,
它們分別代表管道的兩端,管道是一種特殊的文件,它不屬於某種文件系統,它是獨立文件系統,有自己的數據結構,
按照適用範圍:分爲無名管道和有名管道。
無名管道
特點:1)半雙工,數據只能在一個方向上流動。
2)只能在具有血緣關係的進程間使用。
#include<unistd.h>
int pipe(int fd[2]);
成功-- 0,出錯-- -1
fd 參數:返回的是文件描述符,fd[0] 讀端,fd[1]寫端。
1.如果所有指向管道寫端的文件描述符都關閉了(管道寫端的引用計數等於0),而仍
然有進程從管道的讀端讀數據,那麼管道中剩餘的數據都被讀取後,再次read會返回0,就
像讀到文件末尾一樣。
2.如果有指向管道寫端的文件描述符沒關閉(管道寫端的引用計數大於0),而持有管
道寫端的進程也沒有向管道中寫數據,這時有進程從管道讀端讀數據,那麼管道中剩餘的數
據都被讀取後,再次read會阻塞,直到管道中有數據可讀了纔讀取數據並返回。
3.如果所有指向管道讀端的文件描述符都關閉了(管道讀端的引用計數等於0),這時
有進程向管道的寫端write,那麼該進程會收到信號SIGPIPE,通常會導致進程異常終止。講
信號時會講到怎樣使SIGPIPE信號不終止進程。
4.如果有指向管道讀端的文件描述符沒關閉(管道讀端的引用計數大於0),而持有管
道讀端的進程也沒有從管道中讀數據,這時有進程向管道寫端寫數據,那麼在管道被寫滿時
再次write會阻塞,直到管道中有空位置了才寫入數據並返回
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char **argv)
{
int fd[2];
char buf[1024];
pid_t pid;
int n;
if(pipe(fd) < 0){
fprintf(stderr,"error: pipe ");
exit(1);
}
if( (pid = fork()) < 0){
fprintf(stderr,"error: fork");
exit(1);
}
else if(pid == 0){
close(fd[0]);//close read
while(1){
n = read(STDOUT_FILENO,buf,sizeof(buf));
write(fd[1],buf,n);
}
}
else{
close(fd[1]);
while(1){
n = read(fd[0],buf,sizeof(buf));
write(STDOUT_FILENO,buf,n);
}
wait(pid,NULL);
}
exit(0);
}
FIFO(有名管道)
特點:1)兩個無相關的進程之間可以通信
2)FIFO 是一種文件類型,通過stat結構的st_mode成員的編碼可以知道文件是否是FIFO 類型。
#include<sys/stat.h>
int mkfifo(const char *path,mode_t mode);
成功-- 0,出錯-- -1
FIFO 需要用open來打開,對他的I/O 處理和常規文件相似。
FIFO沒有指定O_NONBLOCK,只讀open要阻塞到某個其他進程爲寫而打開這個FIFO爲止;類似的,只寫open也是這樣。
FIFO制定 O_NONBLOCK,只讀open立即返回,若沒有進程爲讀打開FIFO ,返回 -1,並將errno設置爲ENXIO。
client.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<string.h>
#define MAXLINE 512
int main(int argc,char **argv)
{
int fd_rd,fd_wr;
char read_buf[MAXLINE],write_buf[MAXLINE];
int flags,n;
fd_wr = open("public_fifo",O_WRONLY);
fd_rd = open("usr1",O_RDONLY);
while(1){
fgets(write_buf,sizeof(write_buf),stdin);
write(fd_wr,write_buf,strlen(write_buf));
n = read(fd_rd,read_buf,sizeof(read_buf));
write(STDOUT_FILENO,read_buf,n);
}
exit(1);
}
server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<error.h>
#include<string.h>
#include<fcntl.h>
#define MAXLINE 512
int main(int argc,char **argv)
{
int fd_rd,fd_wr;
char read_buf[MAXLINE],write_buf[MAXLINE];
int i = 0,n;
fd_rd = open("public_fifo",O_RDONLY);
if(fd_rd < 0){
fprintf(stderr,"error: open");
exit(1);
}
fd_wr = open("usr1",O_WRONLY);
if(fd_wr < 0){
fprintf(stderr,"error: open");
exit(1);
}
while(1){
n = read(fd_rd,read_buf,sizeof(read_buf));
write(fd_wr,read_buf,n);
}
exit(0);
}