标签:amp pop 之间 部分 缓冲区 lin erro exist exit
进程是系统分配资源的最小单位, 不同进程之间是相互隔离的, Linux常用于进程通信的几种方式有
管道是是基于文件描述符的通信方式, 无名管道只能用于具有亲缘关系之间的进程通信. 建立一个管道时 它会创建两个文件描述符, fd[0] 和 fd[1] , 其中 fd[0] 用于读取数据, fd[1] 用于写入数据, 请看下图 :
如果父进程需要向子进程发送数据通信, 那么可以在父进程上创建一个管道, 关闭父进程的fd[0]和子进程的fd[1], 子进程向父进程发送数据就与之相反.
下面演示了父进程向管道写入数据, 子进程从中读取. sleep()函数确保父进程已经关闭了相应的文件描述符.
#include<stdio.h> #include<sys/types.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<unistd.h> int main(void){ pid_t pid; int pipe_fd[2]; char buf[1024]; const char data[] = "管道测试"; int real_read, real_write; memset(buf, 0, sizeof(buf)); /* 创建管道 */ if(pipe(pipe_fd) < 0){ perror("pipe"); exit(1); } if((pid = fork()) < 0){ perror("fork"); exit(1); }else if(pid == 0){ /* 子进程关闭写描述符, 等待1秒让父进程关闭读描述符*/ close(pipe_fd[1]); sleep(2); if((real_read = read(pipe_fd[0], buf, 1024)) > 0){ printf("读取管道内容 : %s\n", buf); } close(pipe_fd[0]); exit(0); }else{ /* 父进程关闭读描述符, 等待1秒让子进程关闭写描述符 */ close(pipe_fd[0]); sleep(1); if((real_write = write(pipe_fd[1], data, strlen(data))) > 0){ printf("写入管道内容 : %s\n", data); } close(pipe_fd[1]); /* 收集子进程退出信息 */ waitpid(pid, NULL, 0); exit(0); } }
管道读写需要注意几点
相当系统调用, 用于创建连接到另一个进程之间的管道, 这里的进程是指可进行一定操作的可执行文件, 标准流管道把一系列创建过程合并到popen() 中了.
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcntl.h> /* 标准管道流操作 */ int main(void){ FILE *fp; char *cmd = "ps -ef"; char buf[1024]; /* r 文件指针连接到command的标准输出*/ if((fp = popen(cmd, "r")) == NULL){ printf("popen error"); exit(1); } while((fgets(buf, 1024, fp)) != NULL){ printf("%s\n", buf); } pclose(fp); exit(0); }
Linux中专门设立了一个专门的特殊文件系统--管道文件,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据.但在磁盘上只是一个节点,而文件的数据则只存在于内存缓冲页面中,与普通管道一样.
管道文件的读写可能有阻塞问题
对于读进程
对于写进程
下面包含两个程序, 一个用于读取管道, 并在该程序中创建管道, 另一个用于写管道. 首先要调用读程序.
读程序
#include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> #include<errno.h> #include<fcntl.h> #include<stdlib.h> #include<limits.h> /* 由读管道创建 */ #define MYFIFO "/tmp/myfifo" int main(int argc, char *argv[]){ int fd; char buf[PIPE_BUF]; int nread; /* 如果管道不存在则创建 */ if(access(MYFIFO, F_OK) == -1){ /* 0是管道文件, 666是权限 */ if((mkfifo(MYFIFO, 0666) < 0) && (errno != EEXIST)){ perror("create fifo"); exit(1); } } /* 只读阻塞方式打开管道 */ fd = open(MYFIFO, O_RDONLY); if(fd == -1){ perror("open"); exit(1); } /* 读取字符串 */ while(1){ memset(buf, 0, sizeof(buf)); if((nread = read(fd, buf, PIPE_BUF)) > 0){ printf("read %s\n", buf); } } close(fd); exit(0); }
写程序
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<errno.h> #include<fcntl.h> #include<stdlib.h> #include<limits.h> /* 由读管道创建 */ #define MYFIFO "/tmp/myfifo" int main(int argc, char *argv[]){ int fd; char buf[PIPE_BUF]; int nwrite; if(argc <= 1){ printf("Usage: ./fifo_write <strring>"); exit(1); } sscanf(argv[1], "%s", buf); /* 只写阻塞方式打开管道 */ fd = open(MYFIFO, O_WRONLY); if(fd == -1){ perror("open"); exit(1); } /* 写入字符串 */ if((nwrite = write(fd, buf, PIPE_BUF)) > 0){ printf("write : %s\n", buf); } close(fd); exit(0); }
编译运行
读程序 $ gcc fifo_read.c -o fifo_read $ ./fifo_read read 写入1 read 写入2 read 写入3 写程序 $ gcc fifo_write.c -o fifo_write $ ./fifo_write $ ./fifo_write 写入1 write : 写入1 $ ./fifo_write 写入2 write : 写入2 $ ./fifo_write 写入3 write : 写入3
标签:amp pop 之间 部分 缓冲区 lin erro exist exit
原文地址:http://www.cnblogs.com/tanxing/p/6789199.html