Linux学习笔记24——进程管道
一 管道的作用
通常把一个进程的输出通过管道连接到另一个进程的输入。
二 popen和pclose函数
#include <stdio.h> FILE *popen(const char *command, //是要运行的程序名和相应的参数
const char *open_mode //必须是“r”或者“w”,如果是其它值,errno将返回EINVAL
); int pclose(FILE *stream_to_close);
popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。
pclose()调用只在popen启动的进程结束后才返回,如果调用pclose函数时它仍在运行,pclose调用将等待该进程的结束。
例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> int main(){
FILE *read_fp; //要读取的文件描述符
char buffer[BUFSIZ+]; //用来存储读到的文件信息
int chars_read; //实际读取的元素个数 memset(buffer,'\0',sizeof(buffer)); //将数组清零初始化
read_fp=popen("cat test*.c | wc -l","r"); //创建管道,用于显示所有test*.c文件的字数 if(read_fp!=NULL){
chars_read=fread(buffer,sizeof(char),BUFSIZ,read_fp);//从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功返回 0
while(chars_read>){
buffer[chars_read-]='\0'; //清除回车符
printf("Reading:-\n %s\n",buffer);
chars_read=fread(buffer,sizeof(char),BUFSIZ,read_fp);
}
pclose(read_fp); //关闭管道
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
使用shell的一个不太好的影响:针对每个popen调用,不仅要启动一个被请求的程序,还要启动一个shell,即每个popen调用将多启动两个进程。从节省系统资源的角度来看,popen函数的调用成本略高,而且对目标命令的调用比正常方式要慢一些。
三 pipe函数
#include <unistd.h>
int pipe(int fd[]);
pipe函数的参数是一个由两个整数类型的文件描述符组成的数组的指针,两个返回的文件描述符以一种特殊的方式连接起来,写到fd[1]的所有数据都可以从fd[0]读回来,数据基于先进先出的原则(FIFO)进程处理。
对一个已关闭写数据的管道做read调用将返回0而不是阻塞,读取无效的文件描述符将看作是一个错误并返回-1
如果跨越fork调用使用管道,就会有两个不同的文件描述符可以用于向管道写数据,一个在父进程中,一个在子进程中。只有把父子进程中的针对管道的写文件描述符都关闭,管道才会被认为是关闭了,对管道的read调用才会失败。
管道的读写规则:
1 从管道中读取数据
- 如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;
- 当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于 PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据 量)。注:(PIPE_BUF在include/linux/limits.h中定义,不同的内核版本可能会有所不同。Posix.1要求 PIPE_BUF至少为512字节,red hat 7.2中为4096)。
2 从管道中写入数据
向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。
注:只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的SIFPIPE信号,应用程序可以处理该信号,也可以忽略(默认动作则是应用程序终止)。
例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> int main(){
const char some_data[]="";
int file_pipes[];
int data_processed;
pid_t fork_result; if(pipe(file_pipes)==){
fork_result=fork();
if(fork_result==(pid_t)-){
fprintf(stderr,"Fork failure");
exit(EXIT_FAILURE);
}
if(fork_result==){ //子进程
close(); //关闭标准输入,即键盘输入
dup(file_pipes[]); //复制一个文件描述符
close(file_pipes[]); //关闭读操作
close(file_pipes[]); //关闭写操作 execlp("od","od","-c",(char*)); //利用od查看特殊格式的文件内容,-c表示ASCII字符或反斜杠序列,(char*)0参数作用是终止被调用程序的参数列表
exit(EXIT_FAILURE);
}
else{ //主进程
close(file_pipes[]);
data_processed=write(file_pipes[],some_data,strlen(some_data)); //写入数据
close(file_pipes[]);
printf("%d - wrote %d bytes\n",getpid(),data_processed);
}
}
exit(EXIT_SUCCESS);
}
Linux学习笔记24——进程管道的更多相关文章
- Linux学习笔记(六) 进程管理
1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...
- Linux学习笔记25——命名管道(FIFO)
1 命名管道(FIFO) 管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信.后来从管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服.FIFO不同于管道 ...
- linux学习笔记之进程
一.基础知识 1:进程. 1,进程ID: 非负整数,具有唯一性. 1)ID=0的进程:调度进程/交换进程.内核的一部分.不执行任何磁盘上的程序. 2)ID=1的进程:init进程. 1-自举结束时,由 ...
- linux学习笔记-13.进程控制
1.查看用户最近登录情况 lastlastlog 2.查看硬盘使用情况 df 3.查看文件大小 du 4.查看内存使用情况 free 5.查看文件系统 /proc 6.查看日志 ls /var/log ...
- Linux学习笔记(七) 查询系统
1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...
- Linux学习笔记(一) 文件系统
对于每一个 Linux 学习者来说,了解 Linux 文件系统的结构是十分有必要的 因为在 Linux 中一切皆文件,可以说只有深入了解 Linux 的文件系统,才会对 Linux 有更深刻的理解 L ...
- Linux学习笔记(二) 文件管理
了解 Linux 系统基本的文件管理命令可以帮助我们更好的使用 Linux 系统,以下介绍几个常用的文件管理命令 1.pwd pwd 是 Print Working Directory 的简写,用于显 ...
- Linux学习笔记(四) vi编辑器
一.vi 编辑器 vi 编辑器 (Visual Interface) 是所有 Unix 及 Linux 系统下标准的编辑器,相当于 Windows 系统中的记事本 它有三种模式,分别是: Comman ...
- Linux学习笔记(五) 账号管理
1.用户与组账号 用户账号:包括实际人员和逻辑性对象(例如应用程序执行特定工作的账号) 每一个用户账号包含一个唯一的用户 ID 和组 ID 标准用户是系统安装过程中自动创建的用户账号,其中除 root ...
随机推荐
- PHP金字塔的输出
相信学习语言的最初的时候,学到循环的时候,开始一定有种摸不着头脑,想砸电脑的冲动吧 这里就是记录我当初学习的时候,为了通过这个循环,学习的金字塔的输出 1.首先,要了解一个金字塔的输出就要去看它的表达 ...
- Asp.net: WebForm基础上构建Mvc的方法
添加引用: System.Web.Routing System.Web.Abstractions System.Web.Mvc 添加文件夹: Controllers, Views, Views / ...
- [访问系统] C#计算机信息类ComputerInfo (转载)
下载整个包,只下载现有类是不起作用的 http://www.sufeinet.com/thread-303-1-1.html 点击此处下载 using System; using System.Man ...
- C#和SQL操作Xml
#region DataTableToXml public static string DataTableToXml(System.Data.DataTable Dt) { ...
- SQL小细节
平时有些小细节,不留意的话很容易得到错误的答案,我们来看下下面的代码,看看你是否能答对呢? ) ,) SELECT @str = '中国CH',@info='MyTest' SELECT [字符串]= ...
- Win7使用IIS通过域名访问本地程序(网页、css、js等)
一.目的:在本地浏览器里面,输入www.abc.com 可以访问我们本地搭建的网页程序 二.好处:在本地模拟,真实的访问,另外可以设置一些二级域名,例如static.abc.com域名用来存储像图片, ...
- MVC权限模块
设计方向: 1.摒弃SiteMap,避免在容易书写错误的sitemap中书写,导航在controller和action上打标签生成. 2.controller统一继承basecontroller,在b ...
- openssl移植
一.下载openssl 1.下载网址http://www.openssl.org/source/ 2.下载版本openssl-1.0.0q.tar.gz 二.编译openssl为静态库(X86 lin ...
- excel 无法打开文件,提示:向程序发送命令时出现问题
以下的方法以Excel为例,请一个一个的使用,总会有一个适合你的. 1 .兼容性 鼠标右击桌面Excel(或其他)的快捷方式,选“兼容性”,把以管理员身份运行此程序前的勾去掉,就一切ok 了. 如果桌 ...
- CSS3美化表单 移动端可用
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...