- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<sys/types.h>
- #include<unistd.h>
- void read_from_pipe(int fd)
-
{
- char buf[100];
- read(fd,buf,100);
- printf("read from pipe :%s\n",buf);
-
}
- void write_to_pipe(int fd)
-
{
- char *buf="hello pipe!\n";
- write(fd,buf,strlen(buf)+1);
-
}
-
int main()
-
{
- pid_t pid;
- int fd[2];
- int stat;
- if(pipe(fd)){
-
- printf("pipe failed!\n");
- exit(0);
- }
- pid=fork();
- switch(pid){
-
- case -1:
- printf("frok failed\n");
- exit(0);
- case 0:
- close(fd[1]);
- read_from_pipe(fd[0]);
- exit(0);
- default:
- close(fd[0]);
- write_to_pipe(fd[1]);
- wait(&stat);
- exit(0);
- }
- return 0;
- }
当然上面的例子只是单双工通信方式,如果你想要全双工通信那么就建立两个管道进行全双工通信。这里不再赘述,问题是如果父进程创建一个子进程之后,而子进程不知好歹的去执行了另外一个函数去了,这时候就不能再共享文件描述符了,那该怎么办呢? 别急,凡是总是会有办法的,办法就是可以将子进程中的文件描述符重定向到标准输入,当新程序执行的时候从标准输入获取数据时实际上就是从父进程中获取输入数据,那么dup和dup2函数提供了复制文件描述符的功能,两个函数 均在头文件unistd.h中:原型如下: int dup(int oldfd); int dup2(int oldfd,int newfd); 这两个函数调用成功时返回一个oldfd文件描述符的副本,失败返回-1,所不同的是dup函数返回的文件描述符是当前可用文件描述符中的最小数值,而fup2函数则可以利用参数newfd制定欲返回的文件描述符。如果参数newfd指定的文件描述符已经打开,系统先将其关闭,然后将oldfd指定的文件描述赋值到该参数,如果newfd等于oldfd,则dup2返回newfd,而不关闭它。 下面我们具体看一个例子:父进程创建子进程后子进程去执行了另一个函数,通过管道给即将执行的程序传递命令行参数。
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<string.h>
-
int main(int argc,char **argv,char **environ)
-
{
- int fd[2];
- pid_t pid;
- int stat_val;
- if(argc<2){
-
- printf("wrong parameters\n");
- exit(0);
- }
- if(pipe(fd)){
-
- printf("pipe failed\n");
- exit(1);
- }
- pid=fork();
- switch(pid){
-
- case -1:
- printf("fork failed\n");
- exit(1);
- case 0:
- close(0);
- dup(fd[0]);
- execve("ctrlprocess",(void *)argv,environ);
- exit(0);
- default:
- close(fd[0]);
- write(fd[1],argv[1],strlen(argv[1]));
- break;
- }
- wait(&stat_val);
- exit(0);
- }
- #include
- #include
- #include
- int main(int argc,char *argv[])
- {
- int n;
- char buf[1024];
- while(1){
- if((n=read(STDIN_FILENO,buf,1024))>0){
- buf[n]='\0';
- printf("ctrlprocess receives :%s\n",buf);
- if(!strcmp(buf,"exit"))
- exit(0);
- if(!strcmp(buf,"getpid")){
- printf("my pid is %d\n",getpid());
- sleep(3);
- exit(0);
- }
- }
- }
- }
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<fcntl.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #define FIFO_NAME "myfifo"
- #define BUF_SIZE 1024
-
int main()
-
{
- int fd;
- char buf[BUF_SIZE]="hello procwrite,i come frome process named procread";
-
// umask(0);
- if(mkfifo(FIFO_NAME,S_IFIFO|0666)==-1){
-
- perror("mkfifo error!");
- exit(0);
- }
- if((fd=open(FIFO_NAME,O_WRONLY))==-1){
- perror("open fifo error!");
- exit(0);
- }
- write(fd,buf,strlen(buf)+1);
- close(fd);
- exit(0);
- }
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- #include<sys/stat.h>
- #include<fcntl.h>
- #include<sys/types.h>
- #define FIFO_NAME "myfifo"
- #define BUF_SIZE 1024
-
int main(void)
-
{
- int fd;
- char buf[BUF_SIZE];
-
// umask(0);
- fd=open(FIFO_NAME,O_RDONLY);
- read(fd,buf,BUF_SIZE);
- printf("read content:%s\n",buf);
- exit(0);
- }
刚开始由于好奇,当进程退出之后我就看见目录下面生成了一个文件夹myfifo,奇怪的是与其他文件夹的颜色是不同的,我就试图察看它的内容,结果里面是空的,我当时就纳了闷了,明明是一个文件夹,明明写进去东西的,而且另一个进程也从中读出了内容阿,难道是内容被读走了以后就不存在在有名管道中了,但是它不也是一个文件么,写进去的内容怎么会不见呢,难道不是一般的文件?于是上网查了查?结果如下: 有名管道是有名有形的,为了使用这种管道Linux中设立了一个专门的特殊文件系统--管道文件,它存在于文件系统中,任何进程可以在任何时候通过有名管道的路径和文件来访问管道,但是在磁盘上的只是一个节点,而文件的数据则只存在于内存缓冲页面中与普通管道一样。哦,原来是这样,看来它还确实跟普通的文件不一样呢