LInux系统编程学习之《管道的应用》
2013-09-01 13:53
92 查看
今天来总结一些管道的应用
有时候我们需要在父进程和子进程之间进行信息的交换通信,那么管道就是我们选择的一种办法
1.匿名管道
创建匿名管道需要使用pipe函数
例子:我们现在写一个程序,子进程对管道近进行写数据,父进程对管道进行读数据
1.pipe()的调用必须在fork()之前
2.及时关闭不需要的管道句柄
3.使用dup()之前确定定向的目标是最小的文件句柄
4.匿名管道只能实现在父子进程间的通信,如果两个进程之间没有fork()关系,就必须考虑其他的进程通信方法
2.有名管道
为了解决管道不能提供非父子关系进程的通信缺陷,在管道的基础上发展了有名管道
有名管道不仅具有了管道的通信功能,还具有了普通文件的优点(可以被多个进程共享,可长期存在),有效的解决了管道通信的缺点、
建立有名管道的函数如下:
/*
* #include <sys/stat.h>
* int mknod(char * pathname,mode_t mode,dev_t dev);
* 成功返回0,出错返回-1
* pathname:管道的路径
* mode:文件的权限
* dev:设备号,一般填0
*/
下面是一个有名管道的例子,例子中,建立一个有名管道,向管道内读写信息:
创建管道,并等到管道内信息到来:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>
#define FIFO_FILE "sample_fifo_test"
int main()
{
FILE * fp;
char readbuf[80];
umask(0); //清除mask标记
mknod(FIFO_FILE,S_IFIFO | 0666,0); //创建有名管道
while (1)
{
fp = fopen(FIFO_FILE,"r"); //打开管道
fgets(readbuf,80,fp); //读取管道中信息
printf("Receiver string:%s\n",readbuf); //打印信息
fclose(fp); //使用完关闭管道
}
return 0;
}
打开管道,向管道内写入信息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>
#define FIFO_FILE "sample_fifo_test"
int main()
{
FILE * fp;
char buf[255];
while (NULL != gets(buf)) //获取项管道内写入的信息
{
fp = fopen(FIFO_FILE,"w"); //打开管道
fputs(buf,fp); //写入信息到管道内
fclose(fp); //关闭管道
}
return 0;
}
有名管道使用注意:
1.有名管道一次写入的数据量有限制,在头文件<linux/limits.h>中的PIPE_BUF可以获取,如果一次写入的数据超过这个值,则会分多次写入,这时如果有多个程序在使用管道,则可能会出现数据不一致的情况
2.有名管道必须同时有读/写两个进程。如果一个进程试图向一个没有读入端进程的有名管道写入数据,一个SIGPIPE信号会产生。
有时候我们需要在父进程和子进程之间进行信息的交换通信,那么管道就是我们选择的一种办法
1.匿名管道
创建匿名管道需要使用pipe函数
/* * #include <unistd.h> * int pipe(int pipedes[2]); * 成功返回0,出错返回-1,错误记录在errno变量中 * pipedes是用来定义管道的读取文件 * pipedes[0]用于从管道中读,pipedes[1]用于从管道中写 */
例子:我们现在写一个程序,子进程对管道近进行写数据,父进程对管道进行读数据
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> int main(int argc,char ** argv) { int fd[2],nbytes; pid_t childpid; char string[] = "Hello world!\n"; char readbuffer[80]; pipe(fd); //创建管道,传入一个数量为2的一维数组即可 if ((childpid = fork())==-1) //创建子进程 { perror("fork"); _exit(1); } if (0 == childpid) { close(fd[0]); //子进程关闭读取管道,即fd[0] write(fd[1],string,strlen(string)); //子进程写入数据到管道中 _exit(0); } else { close(fd[1]); //父进程关闭写入管道,即fd[1] nbytes = read(fd[0],readbuffer,sizeof(readbuffer)); //父进程从管道中读取数据 printf("Receive string:%s",readbuffer); //把读到的数据打印出来 } return 0; }使用匿名管道需要注意的地方:
1.pipe()的调用必须在fork()之前
2.及时关闭不需要的管道句柄
3.使用dup()之前确定定向的目标是最小的文件句柄
4.匿名管道只能实现在父子进程间的通信,如果两个进程之间没有fork()关系,就必须考虑其他的进程通信方法
2.有名管道
为了解决管道不能提供非父子关系进程的通信缺陷,在管道的基础上发展了有名管道
有名管道不仅具有了管道的通信功能,还具有了普通文件的优点(可以被多个进程共享,可长期存在),有效的解决了管道通信的缺点、
建立有名管道的函数如下:
/*
* #include <sys/stat.h>
* int mknod(char * pathname,mode_t mode,dev_t dev);
* 成功返回0,出错返回-1
* pathname:管道的路径
* mode:文件的权限
* dev:设备号,一般填0
*/
下面是一个有名管道的例子,例子中,建立一个有名管道,向管道内读写信息:
创建管道,并等到管道内信息到来:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>
#define FIFO_FILE "sample_fifo_test"
int main()
{
FILE * fp;
char readbuf[80];
umask(0); //清除mask标记
mknod(FIFO_FILE,S_IFIFO | 0666,0); //创建有名管道
while (1)
{
fp = fopen(FIFO_FILE,"r"); //打开管道
fgets(readbuf,80,fp); //读取管道中信息
printf("Receiver string:%s\n",readbuf); //打印信息
fclose(fp); //使用完关闭管道
}
return 0;
}
打开管道,向管道内写入信息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <linux/stat.h>
#define FIFO_FILE "sample_fifo_test"
int main()
{
FILE * fp;
char buf[255];
while (NULL != gets(buf)) //获取项管道内写入的信息
{
fp = fopen(FIFO_FILE,"w"); //打开管道
fputs(buf,fp); //写入信息到管道内
fclose(fp); //关闭管道
}
return 0;
}
有名管道使用注意:
1.有名管道一次写入的数据量有限制,在头文件<linux/limits.h>中的PIPE_BUF可以获取,如果一次写入的数据超过这个值,则会分多次写入,这时如果有多个程序在使用管道,则可能会出现数据不一致的情况
2.有名管道必须同时有读/写两个进程。如果一个进程试图向一个没有读入端进程的有名管道写入数据,一个SIGPIPE信号会产生。
相关文章推荐
- 一个管道的应用例子
- 进程间通信系列 之 命名管道FIFO及其应用实例
- 【shell编程基础3】shell编程的组合应用之二:管道及其命令
- 命名管道的应用
- 学习ASP.NET Core, 怎能不了解请求处理管道[4]: 应用的入口——Startup
- linux匿名管道的应用
- 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较
- 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
- 新一篇: 设计模式之管道和过滤器的应用
- 管道的应用(pipe)《深入分析Linux内核源码》 http://blog.csdn.net/wangpengqi/article/details/7996182
- 应用管道实现父子进程之间的通信
- linux 中 xargs、cut 以及管道综合应用
- 五种IO 模式——阻塞(默认IO模式),非阻塞(常用语管道),IO多路复用(IO多路复用的应用场景),信号IO,异步IO
- linux驱动开发-字符设备初级应用(管道)
- linux应用编程--命名管道
- 关于管道命令的一些简单应用
- 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
- [Linux管道和IPC]管道的实际应用1
- Linux进程间通信——命名管道应用实例
- 有名管道应用(返回字符串)