管道
来源:互联网 发布:毛主 感谢日本 知乎 编辑:程序博客网 时间:2024/04/28 11:33
管道
管道:一个进程连接到另一个进程的一个数据流称为一个“管道”。
我们通常把是把一个进程的输出连接或“管接”(经过管道来连接)到另一个进程的输入。
作用:进程间通信
信号函数sigqueue()进程间只能传送int类型数据,管道可以传送任何数据。
匿名管道和有名管道:
匿名管道:1半双工,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
2只能作用于有亲缘关系的。
有名管道:可以作用于不是亲缘关系的管道。
//******************************************匿名管道pipe()****************************************************
// 2013.10.20.
// 函数名:int pipe(int file_descriptor[2]);
// 功能:创建一无名管道
// 参数:file_descriptor:文件描述符数组,其中file_descriptor[0]表示读端,file_descriptor[1]表示写端*
// 返回值:成功返回0,失败返回错误代码
//******************************************匿名管道pipe()****************************************************
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd[2]; //定义一个文件描述符数组
int pip = pipe(fd); //将文件描述符放入管道
if (pip == -1)
{
perror("Pipe Errpr!\n");
}
int pid = fork();
if (pid > 0)
{
close(fd[0]); //单双工,让它只能单端操作
write(fd[1], "HelloWorld!\n", strlen("HelloWorld\n")); //fd[1]为管道的写入段,数据将会流入管道的另一端fd[0](另一进程)
}
else if (pid == 0)
{
close(fd[1]); //单双工,让它只能单端操作
char acBuf[1024];
read(fd[0], acBuf, 1024); //fd[0]为管道的读取端
printf("Data : %s\n", acBuf);
}
else
{
perror("Fork error!");
exit(1);
}
return 0;
}
//************************建立两个管道,让进程能够双向通信*********************************************************
int main()
{
int fd[2]; //定义一个文件描述符数组
pipe(fd); //将文件描述符放入管道
int fd1[2]; //再定义一个文件描述符数组用来搭建再一个管道
pipe(fd1);
int pid = fork();
if (pid > 0)
{
char acBuf[1024];
close(fd[0]); //单双工,让它只能单端操作
close(fd1[1]);
write(fd[1], "HelloWorld!\n", strlen("HelloWorld\n")); //fd[1]为管道的写入段,数据将会流入管道的另一端fd[0](另一进程)
sleep(3);
read(fd1[0], acBuf, 1024);
printf("Data1 : %s\n", acBuf);
}
else if (pid == 0)
{
close(fd[1]); //单双工,让它只能单端操作
close(fd1[0]);
char acBuf[1024];
read(fd[0], acBuf, 1024); //fd[0]为管道的读取端
printf("Data : %s\n", acBuf);
//fd1[1]为管道的写入段,数据将会流入管道的另一端fd1[0](另一进程)
write(fd1[1], "Hi Good morning!\n", strlen("Hi Good morning!\n"));
}
else
{
perror("Fork error!");
exit(1);
}
return 0;
}
/*******************************************************************************************************
下面有两端有名管道的代码
前面一段代码为读端
后面的代码为写端(一秒往有名管道里面写一个HelloWorld!)
编译后运行这两个文件,write后台运行,read前台运行
********************************************************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//******************************************有名管道****************************************************
// 2013.10.20.陈顺明
//创建
// 用shell命令创建"mkfifo + 管道名(如fifo)" prw-r--r-- 1 root root 0 10-20 17:05 fifo(p开头为管道)
//也可以在程序中创建:int mkfifo(const char *filename,mode_t mode)
//有名管道作用:匿名管道只能作用于亲缘进程关系之间,有名管道不限于亲缘关系
//有名管道:可以理解为是一个文件,两个进程通过文件读取来中转数据(对它的操作和文件读写一样)
//******************************************有名管道****************************************************
int main()
{
int fd = open("/ming/fifo", O_RDONLY); //只写方式打开(只读或者只写方式打开,不能只读只写方式打开)
if (fd < 0)
{
perror("Open Error!\n");
exit(1);
}
while(1)
{
char acBuf[1024] = {0};
memset(acBuf, 0, 1024);
int read_size = read(fd, acBuf, 1024);
if (read_size > 0)
{
printf("Read Data: %s \n", acBuf);
}
}
return 0;
}
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//******************************************有名管道****************************************************
// 2013.10.20.陈顺明
//创建
// 用shell命令创建"mkfifo + 管道名(如fifo)" prw-r--r-- 1 root root 0 10-20 17:05 fifo(p开头为管道)
//也可以在程序中创建:int mkfifo(const char *filename,mode_t mode)
//有名管道作用:匿名管道只能作用于亲缘进程关系之间,有名管道不限于亲缘关系
//有名管道:可以理解为是一个文件,两个进程通过文件读取来中转数据(对它的操作和文件读写一样)
//******************************************有名管道****************************************************
int main()
{
int fd = open("/ming/fifo", O_WRONLY); //只写方式打开
if (fd < 0)
{
perror("Open Error!\n");
exit(1);
}
while(1)
{
write(fd, "HelloWorld!\n", strlen("HelloWorld!\n"));
sleep(1);
}
return 0;
}
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//******************************************匿名管道pipe()****************************************************
// 2013.10.20.陈顺明
// int dup(int oldfd); dup系统调用从头开始搜文件描述符数组,并且在找到第一个空闲文件描述符时完成它的复制
// int dup2(int oldfd, int newfd); dup2系统调用复制操作之前,如果newfd已被打开,先关闭。
// int fcntl(int oldfd,F_DUPFD,int minifd)
//功能:复制文件描述符
//******************************************匿名管道pipe()****************************************************
//**************************************************dup()*****************************************************
int main()
{
int fd = dup(1); //文件描述符1为标准输出
write(fd, "HelloWorld!\n", strlen("HelloWorld!\n")); //结果是打印"HelloWorld!"
return 0;
}
//**************************************************Shell中运用管道"ls -al | wc"的实现*************************
int main()
{
int fd[2];
pipe(fd);
int pid = fork();
if (pid > 0)
{
close(0); //关闭文件描述符0,让它成为第一个空闲文件描述符
dup(fd[0]); //找到第一个空闲文件描述符0(标准输入),完成它的复制
close(fd[0]);
close(fd[1]);
execlp("wc", "wc", NULL);
}
else if(pid == 0)
{
close(1);
dup(fd[1]); //把文件描述符1(标准输出) *复制给fd[1]管道的写端*
close(fd[0]);
close(fd[1]);
execlp("ls", "ls", "-al", NULL); //这条命令会在管道的写端进入留到另一进程的读端fd[0]
}
else
{
perror("Fork Error!\n");
exit(1);
}
return 0;
}
//**************************************************dup2()*****************************************************
int main()
{
int fd = open("/ming/myfile1", O_RDWR | O_CREAT , S_IRWXU);
if (fd < 0)
{
perror("Open Error!\n");
exit(1);
}
dup2(1, fd); //把1复制给fd(是哟dup2会先把之前的fd关闭再把1复制给它)
write(fd, "Hi ChenShunMing!\n", strlen("Hi ChenShunMing!\n"));
return 0;
}
//******************************************popen()****************************************************
// 2013.10.20.陈顺明
// FILE* popen(const char *command, const char *open_mode)
// 功能 :允许一个程序把另外一个程序当作一个新的进程来启动,并能对它发送数据或接收数据
// command:待运行程序的名字和相应的参数
// open_mode:必须是“r(返回的指针是给用户读的)”或“w(返回的指针是要用户往里写的)”
// 如果操作失败,popen会返回一个空指针
//******************************************popen()****************************************************
//****************************用popen()实现管道"ls -al | wc"功能
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *rFile = popen("ls -al", "r"); //把结果写到rFile文件里面
char acBuf[1024];
fread(acBuf, 1, 1024, rFile); //读文件
// printf("Read Data : %s", acBuf);
pclose(rFile); //用popen打开的用pclose关闭
FILE *wFile = popen("wc", "w"); //需要往wFile文件里面写数据
fwrite(acBuf, 1, strlen(acBuf), wFile);
pclose(wFile);
return 0;
}
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- 管道
- <>管道
- 管道
- 管道
- 管道
- 管道
- 管道
- |管道
- Windows SC命令总结
- 状态编码与解码器
- [LeetCode] Implement strStr() 字符串子串
- 细分球代码 (参考opengl redbook 的第二章)
- 单链表基本实现(c++)
- 管道
- android隐藏标题栏(titlebar)以及全屏显示
- Boost的Serialization和SmartPoint搭配使用
- 单文档相关
- Class.forName,new和loadClass之一二三
- OpenGL入门学习[三]
- C++随机数--——生成任意范围内等概率随机数“足够好”的做法
- OpenGL入门学习(一)
- CMS GC总结