Linux c 管道文件-进程间的通信 mkfifo、pipe

管道文件:

1. 创建管道mkfifo(命名管道)

#include<sys/stat.h>

intmkfifo( const char *pathname,mode_t mode);

参数:pathname:管道文件名/路径+文件名

Mode: 文件权限

返回值:0成功,-1失败

2. 体会管道文件的特点

案例:

fifoA fifoB

建立管道 打开管道

打开管道 读数据

写数据 关闭管道

关闭管道

删除管道

代码:

fifoA.c

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<fcntl.h>

#include<sys/stat.h>

#include<signal.h>

int fd;

void end( ints)

{

//关闭文件、删除管道文件

close(fd);

unlink( “text.pipe” );

exit(-1);

}

void main()

{

int i=0;

signal( SIGINT , end);

//创建管道

mkfifo(“text.pipe” , 0666);

//打开文件

fd=opend( “text.pipe”, O_RDWR);

//循环写入数据

while(1)

{

write(fd, & i , 4);

sleep(1);

i++;

}

}

fifoB.c

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/stat.h>

#include<signal.h>

int fd;

void end( ints)

{

//关闭文件

close(fd);

exit(-1);

}

void main()

{

int i=0;

signal( SIGINT , end);

//打开文件

fd=opend( “text.pipe”, O_RDWR);

//循环读取数据

while(1)

{

read(fd, & i , 4);

printf(“%d”,i);

}

}

程序运行说明:

程序A运行后往管道文件中写入数据,程序B从管道文件中读取数据,当程序B结束,程序A运行,并稍后程序B继续运行时,程序B读到的数据是继续上次结束时的下一个数据。

当程序A结束,程序B运行时,程序B阻塞挂起。

总结:

1.read没有数据,read会阻塞,而且read后数据是被删除。

2.数据是有序的

3.打开的描述符号可以读写(two-way双工)(建议用只读或只写打开)

或者用shutdown函数关闭读或写关闭,变成单工

4.管道文件关闭后,数据不持久.(程序如不删除管道,程序结束后,无法读到数据)

5.管道的数据实际是存储在内核的缓冲中。(管道文件不是一个真实的文件,是内存的虚拟文件)

注:其实管道文件只是内存中的一个先进先出的数据结构,文件只是个载体,打开管道文件时只是对应了描述符是一个先进先出的内存结构而不是一个真实的文件。(当我们的程序运行后,我们删除那个文件,程序可照常运行不受任何影响)

匿名管道:

发现有名的管道的名字仅仅是内核识别是否返回同一个fd的标示.

所以当管道名失去表示作用的时候,实际可以不要名字.

在父子进程之间:打开文件描述后创建进程.

父子进程都有描述符号. 管道文件没有价值.

所以在父子进程中引入一个没有名字的管道:匿名管道.

结论:

匿名管道只能使用在父子进程.

案例:

匿名管道的创建

体会匿名管道的特点

函数:

#include<unistd.h>

int pipe( int filedes[2] );

参数:数组指针(返回值),返回两个文件描述符

fd[0]:只读(不能写)

fd[1]:只写(不能读)

返回值:0成功、-1失败

pipe函数做了:

创建管道 打开管道 拷贝管道(两个) 关闭读写(一个关闭读,一个关闭写)

例子:

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

void main()

{

intfd[2];

intr;

charbuf[20];

r=pipe(fd);

write( fd[1] , “hello” , 5);

write(fd[1] , “world”, 5);

r=read( fd[0], buf, 20);

buf[r]=0;

printf(“%s\n”,buf);

}

父子进程例子:

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

void main()

{

intfd[2];

pipe( fd );

if(fork())

{

//parent

close(fd[0]); //只负责写入数据

while(1)

{

write( fd[1] ,”hello”);

sleep(1);

}

}

else

{

//child

close(fd[1]); //只负责读数据

char buf[20];

int r;

while(1)

{

r=read( fd[0] , buf , 20);

buf[r]=0;

printf(“::%s\n”,buf);

}

}

}

注:建议一个进程的一个匿名管道只负责读或写,不要即读即写,否则会导致数据混乱。所以,上面的程序父进程关闭了读文件描述符,子进程关闭了写文件描述符。父进程只负责写入数据,子进程只负责读取数据。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值