运用管道(pipe)进行进程间通信

来源:互联网 发布:金山数据恢复大师官网 编辑:程序博客网 时间:2024/05/21 01:50

   在linux系统中,管道是一种特殊的文件,它的主要作用是实现进程间的通信。

   管道的一个显著特点是:当一个管道建立后,将获得两个文件描述符,分别用于对管道读取和写入,通常将其称为管道的写入端和读取端,从写入端写入管道的任何数据都可以从读取端读取。对于一个进程来说,管道的写入和读取操作与写入和读取一个普通文件没有区别,只是在内核中通过这种机制来实现进程间的通信。

  管道的局限性:

 1,管道只能用于两个进程间的通信,不能用与多个(>3)进程间的通信。

 2,这两个进程要有同源性,即他们必须是最终由同一个进程所派生的进程。

 3,管道是半双工方式的,即只允许单向传输数据。


创建pipe管道函数:
int pipe(int file_descriptor[2]);
函数pipe填充的两个整数的含义是两个文件描述符,任何向file_descriptor[1](写入端)写入的数据,可以从file_descriptor[0](读取端)中读取,并且写入的数据符合先入先出的规则.

pipe.c:

 

/* * ===================================================================================== * *       Filename:  pipe.c * *    Description:   * *        Version:  1.0 *        Created:  2012年03月11日 14时21分11秒 *       Revision:  none *       Compiler:  gcc * *         Author:  MaZheng (blog.csdn.net/mazheng1989), mazheng19891019@gmail.com *        Company:  Dalian University Of Technology * * ===================================================================================== */#include<stdio.h> #include <unistd.h>#include <string.h>#include <sys/types.h>#include<stdlib.h>int main() { int data_processed; int file_pipes[2]; const char some_data[]="123"; char buffer[BUFSIZ+1]; int fork_result; memset(buffer,'\0',sizeof(buffer)); if(pipe(file_pipes)==0){ fork_result=fork(); /* 设置进程 */ if (fork_result==-1){ /* 判断设置进程是否出错 */ fprintf(stderr,"Fork failure"); exit(1); } /* 下面判断,若是是子进程则读管道数据,父进程则向管道写数据 */ if(fork_result==0){ /* 判断是否子进程 */ data_processed=read(file_pipes[0],buffer,BUFSIZ); /* 从管道读数据 */ close(file_pipes[1]);printf("Read %d bytes:%s\n",data_processed,buffer); exit(1); } else { /* 父进程 */ data_processed=write(file_pipes[1],some_data,strlen(some_data)); /* 向管道写数据 */   close(file_pipes[0]);printf("Wrote %d bytes\n",data_processed); } } exit(1); }
程序运行:./pipe
执行结果:
Wrote 3 bytes
Read 3 bytes:123
利用管道进行通信成功!


man pipe

里面的例子:

#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>intmain(int argc, char *argv[]){int pipefd[2];pid_t cpid;char buf;if (argc != 2) {fprintf(stderr, "Usage: %s <string>\n", argv[0]);exit(EXIT_FAILURE);}if (pipe(pipefd) == -1) {perror("pipe");exit(EXIT_FAILURE);}cpid = fork();if (cpid == -1) {perror("fork");exit(EXIT_FAILURE);}if (cpid == 0) {    /* Child reads from pipe */close(pipefd[1]);          /* Close unused write end */while (read(pipefd[0], &buf, 1) > 0)write(STDOUT_FILENO, &buf, 1);write(STDOUT_FILENO, "\n", 1);close(pipefd[0]);_exit(EXIT_SUCCESS);} else {            /* Parent writes argv[1] to pipe */close(pipefd[0]);          /* Close unused read end */write(pipefd[1], argv[1], strlen(argv[1]));close(pipefd[1]);          /* Reader will see EOF */wait(NULL);                /* Wait for child */exit(EXIT_SUCCESS);}}




原创粉丝点击