linux有名管道 mkfifo,linux之有名管道

二 有名管道

特点:在文件系统中存在一个名字,管道存在于内核空间

A.创建有名管道

int mkfifo(char *filename,int mode)

例如:

//如果创建有名管道,是由于管道文件存在而失败

//,认为是正常的情况

if(mkfifo(filename,0666) < 0 && errno != EEXIST)

{

.....

}

B.打开有名管道文件

注意:

1.有名管道一端以只读的方式打开,此时会阻塞,直到另一端以写的方式打开

2.有名管道一端以只写的方式打开,此时会阻塞,直到另一端以读的方式打开

3.如果以读写方式打开,此时不阻塞

三 管道特性(无名管道和有名管道)

A.读管道

1. 写端存在

读管道,管道中有数据,读取数据;管道中没有数据,阻塞。

2.写端不存在

读管道,管道中有数据读取数据,管道中没有数据的时候,不会阻塞,read立即返回0

B.写管道

1.读端存在

写管道,管道空闲,写入数据,管道满,写阻塞

2.读端不存在

写管道,此时写操作没有意义,内核会向写管道的进程发送SIGPIPE信号,此信号默认操作是杀死进程

用创建进程的方式来实现两个进程交谈

在A.c中代码如下

#include #include #include #include #include #include #include #include #include

int read_fifo(const char *filename)

{

int n;

char buf[1024];

int fifo_fd;

//打开有名管道

if((fifo_fd = open(filename,O_RDONLY)) < 0)

{

fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));

}

printf("Open fifo success for readonly.\n");

//从管道中读取数据,并且打印,如果读"quit",结束进程

while(1)

{

//读管道

n = read(fifo_fd,buf,sizeof(buf) - 1);

buf[n] = '\0';

if(n == 0)

{

kill(getppid(),9);

break;

}

printf("Read %d bytes : %s.\n",n,buf);

}

return 0;

}

int write_fifo(const char *filename,int pid)

{

char buf[1024];

int fifo_fd;

//打开有名管道

if((fifo_fd = open(filename,O_WRONLY)) < 0)

{

fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));

}

while(1)

{

printf(">");

fgets(buf,sizeof(buf),stdin);

buf[strlen(buf) - 1] = '\0';

//写管道

write(fifo_fd,buf,strlen(buf));

if(strncmp(buf,"quit",4) == 0)

{

kill(pid,9);

break;

}

}

return 0;

}

//./a.out FIFO1 FIFO2

int main(int argc, const char *argv[])

{

pid_t pid;

//创建有名管道文件

if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)

{

fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));

exit(EXIT_FAILURE);

}

//创建有名管道文件

if(mkfifo(argv[2],0666) < 0 && errno != EEXIST)

{

fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));

exit(EXIT_FAILURE);

}

if((pid = fork()) < 0)

{

perror("Fail to fork");

exit(EXIT_FAILURE);

}

if(pid == 0)

{

read_fifo(argv[2]);

}

if(pid > 0)

{

write_fifo(argv[1],pid);

}

exit(EXIT_SUCCESS);

}

在B.c中代码如下:

#include #include #include #include #include #include #include #include #include

int read_fifo(const char *filename)

{

int n;

char buf[1024];

int fifo_fd;

//打开有名管道

if((fifo_fd = open(filename,O_RDONLY)) < 0)

{

fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));

}

printf("Open fifo success for readonly.\n");

//从管道中读取数据,并且打印,如果读"quit",结束进程

while(1)

{

//读管道

n = read(fifo_fd,buf,sizeof(buf) - 1);

buf[n] = '\0';

if(n == 0)

{

kill(getppid(),9);

break;

}

printf("Read %d bytes : %s.\n",n,buf);

}

return 0;

}

int write_fifo(const char *filename,int pid)

{

char buf[1024];

int fifo_fd;

//打开有名管道

if((fifo_fd = open(filename,O_WRONLY)) < 0)

{

fprintf(stderr,"Fail to open %s : %s.\n",filename,strerror(errno));

}

while(1)

{

printf(">");

fgets(buf,sizeof(buf),stdin);

buf[strlen(buf) - 1] = '\0';

//写管道

write(fifo_fd,buf,strlen(buf));

if(strncmp(buf,"quit",4) == 0)

{

kill(pid,9);

break;

}

}

return 0;

}

//./a.out FIFO1 FIFO2

int main(int argc, const char *argv[])

{

pid_t pid;

//创建有名管道文件

if(mkfifo(argv[1],0666) < 0 && errno != EEXIST)

{

fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));

exit(EXIT_FAILURE);

}

//创建有名管道文件

if(mkfifo(argv[2],0666) < 0 && errno != EEXIST)

{

fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno));

exit(EXIT_FAILURE);

}

if((pid = fork()) < 0)

{

perror("Fail to fork");

exit(EXIT_FAILURE);

}

if(pid == 0)

{

read_fifo(argv[1]);

}

if(pid > 0)

{

write_fifo(argv[2],pid);

}

exit(EXIT_SUCCESS);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值