c中linux中进程间通信IPC之匿名管道PIPE在实战中的应用??
【案例1】
//多进程中,子进程未执行??
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#define N 10
#define MAX 100
//子进程为什么没有执行??子进程未打印??只执行父进程??
int child_read_pipe(int fd)
{
char buf[N];
int n = 0;
//while(1){
n = read(fd, buf, sizeof(buf));
printf("Read %d bytes:%s\n", n, buf);
//if(strncmp(buf, "quit", 4) == 0)
//break;
//}
return 0;
}
int father_write_pipe(int fd)
{
char buf[MAX] = {0};
//while(1){
printf(">");
//fgets(buf, sizeof(buf), stdin);
sprintf(buf, "This is father process!\nquit\n");
buf[strlen(buf)-1] = '\0';
write(fd, buf, strlen(buf));
printf("Write bytes is:%s\n", buf);
usleep(500);
//if(strncmp(buf, "quit", 4) == 0)
//break;
//}
return 0;
}
//为什么子进程读的时候未执行,父进程写的时候执行了??
int main()
{
pid_t pid;// 也可以定义为int pid
int n, m;
int fd[2];
char buf[1000 * 6] = {0}, rbuf[100] = {0};
pid = fork();
if(pipe(fd) < 0)
{
perror("Fail to pipe!");
exit(EXIT_FAILURE);
}
if(pid < 0)
{
perror("Fail to fork!");
exit(EXIT_FAILURE);
}else if(pid == 0){
printf("Read port begin.\n");
child_read_pipe(fd[0]);
printf("Read port begin.\n");
/**
//sleep(5);
//为什么读出来的内容,是前10个字符,后面是全部内容??
//close(fd[1]);
m = read(fd[0], rbuf, sizeof(rbuf));
printf("Read %d bytes to pipe and size is:%s.\n", m, rbuf);
*/
sleep(3);
}else{
printf("Write port begin.\n");
father_write_pipe(fd[1]);
printf("Write port close.\n");
/**
//close(fd[0]);
sprintf(buf, "This is parent process!");
//while(1)
//{
n = write(fd[1], buf, sizeof(buf));
printf("Write %d bytes to pipe and size is:%s.\n", n, buf);
//}
*/
printf("Read end, errno is:%d\n", errno);
perror("Read result");
}
//exit(EXIT_SUCCESS);
//return 0;
}
【案例2】
//父进程读取文件的内容,写到无名管道,子进程从管道中读取内容写到另一个文件??
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#define MAX 100
int child_work(int pfd,char *fname)
{
int n,fd;
char buf[MAX];
if((fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",fname,strerror(errno));
return -1;
}
while( n = read(pfd,buf,sizeof(buf)) )
{
write(fd,buf,n);
}
close(pfd);
return 0;
}
int father_work(int pfd,char *fname)
{
int fd,n;
char buf[MAX];
if((fd = open(fname,O_RDONLY)) < 0)
{
fprintf(stderr,"Fail to open %s : %s.\n",fname,strerror(errno));
return -1;
}
while(n = read(fd,buf,sizeof(buf)))
{
write(pfd,buf,n);
}
close(pfd);
return 0;
}
//思考:父进程什么时候结束,子进程什么时候结束?
int main(int argc,char *argv[])
{
int pid;
int fd[2];
/** */
FILE * fp;
fp = fopen ("file.txt", "w+");
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014);
fclose(fp);
//初始化参数失败??
//argv[1] = "file.txt";
//argv[2] = "wfile.txt";
system("ls");
if(argc < 3)
{
fprintf(stderr, "usage %s argv[1] argv[2].\n", argv[0]);
printf("2 usage %X argv[1] argv[2].\n", argv[0]);
perror("3 usage error");
exit(EXIT_FAILURE);
}
if(pipe(fd) < 0)
{
perror("Fail to pipe");
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}else if(pid == 0){
close(fd[1]);
child_work(fd[0],argv[2]);
}else{
close(fd[0]);
father_work(fd[1],argv[1]);
wait(NULL);
}
exit(EXIT_SUCCESS);
}
【命令行管道符案例】
以ps -ef | grep "run"来举例功能:在ps -ef查找到的数据中过滤出含有run字符的所在行数据。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
int pipefd[2] = {-1};
if (pipe(pipefd) < 0)
{
perror("pipe error");
return -1;
}
//ps程序
pid_t ps_pid = fork();
if (ps_pid == 0)
{
//将标准输出重定向到管道的写端,将要打印的数据写到管道中
dup2(pipefd[1], 1);
//将该子进程替换成ps进程
execlp("ps", "ps", "-ef", NULL);
exit(0);
}
//grep程序
pid_t grep_pid = fork();
if (grep_pid == 0)
{
//关闭写端,防止读完数据后发生阻塞
close(pipefd[1]);
//将标准输入重定向到管道的读端,从0-标准输入读取的数据相当于从管道读取数据
dup2(pipefd[0], 0);
//将该子进程替换成grep进程 grep ssh
execlp("grep", "grep", "run", NULL);
exit(0);
}
//关闭父进程的读取端
close(pipefd[0]);
close(pipefd[1]);
waitpid(ps_pid, NULL, 0);
waitpid(grep_pid, NULL, 0);
/* 我的第一个命令行管道符 C 程序 */
printf("stdout Hello, World! \n");
return 0;
}