linux中匿名管道和命名管道
2017-03-09 16:43
309 查看
管道
匿名管道
1、创建管道和父子进程,子进程关闭读端,父进程关闭写端,子进程写,父进程读。#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> int main() { int pipefd[2] = {0,0}; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } pid_t id = fork();// creat child progress if(id < 0){ perror("fork"); return 2; }else if(id == 0){//child->write close(pipefd[0]); const char* msg = "hello world"; int count = 5; while(count){ write(pipefd[1],msg,strlen(msg)); count--; sleep(1); } close(pipefd[1]); exit(0); }else{//father->read close(pipefd[1]); int count = 5; char buf[128]; while(count){ ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1); if(_s > 0){ buf[_s] = '\0'; printf("%s\n",buf); }else if(_s == 0){ printf("close\n"); break; }else{ perror("read"); return 3; } count--; } close(pipefd[0]); } return 0; }
2、如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),而仍然有进程 从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> int main() { int pipefd[2] = {0,0}; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } pid_t id = fork();// creat child progress if(id < 0){ perror("fork"); return 2; }else if(id == 0){//child->write close(pipefd[0]); const char* msg = "hello world"; int count = 5; while(count){ write(pipefd[1],msg,strlen(msg)); count--; sleep(1); } close(pipefd[1]); exit(0); }else{//father->read close(pipefd[1]); int count = 5; char buf[128]; while(1){ ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1); if(_s > 0){ buf[_s] = '\0'; printf("child->father:%s\n",buf); }else if(_s == 0){ printf("pipe write is close\n"); break; }else{ perror("read"); return 3; } count--; } close(pipefd[0]); } return 0; }
3、如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),而持有管道写端的 进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> int main() { int pipefd[2] = {0,0}; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } pid_t id = fork();// creat child progress if(id < 0){ perror("fork"); return 2; }else if(id == 0){//child->write close(pipefd[0]); const char* msg = "hello world"; int count = 5; while(1){ write(pipefd[1],msg,strlen(msg)); count--; if(count == 0) { sleep(5); count--; } sleep(1); } close(pipefd[1]); exit(0); }else{//father->read close(pipefd[1]); int count = 5; char buf[128]; while(1){ ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1); if(_s > 0){ buf[_s] = '\0'; printf("child->father:%s\n",buf); }else if(_s == 0){ printf("pipe write is close\n"); break; }else{ perror("read"); return 3; } count--; } close(pipefd[0]); } return 0; }
4、如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于0),这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止.
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> int main() { int pipefd[2] = {0,0}; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } pid_t id = fork();// creat child progress if(id < 0){ perror("fork"); return 2; }else if(id == 0){//child->write close(pipefd[0]); const char* msg = "hello world"; int count = 5; while(1){ write(pipefd[1],msg,strlen(msg)); count--; sleep(1); } close(pipefd[1]); exit(0); }else{//father->read close(pipefd[1]); int count = 5; char buf[128]; while(1){ ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1); if(_s > 0){ buf[_s] = '\0'; printf("child->father:%s\n",buf); }else if(_s == 0){ printf("pipe write is close\n"); break; }else{ perror("read"); return 3; } count--; if(count == 0){ close(pipefd[0]); break; } } } int status = 0; pid_t ret = waitpid(id,&status,0); if(ret > 0){ printf("exit code: %d,signl: %d\n",(status>>8)&0xff,status&0xff); } return 0; }
命名管道
1、client端#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<errno.h> #include<string.h> int main() { int fd = open("./fifo",O_WRONLY); if(fd < 0){ perror("open"); return 2; } char buf[128]; while(1){ printf("Please Enter# "); fflush(stdout); ssize_t s = read(0,buf,sizeof(buf)); if(s > 0){ buf[s-1] = '\0'; write(fd,buf,strlen(buf)); }else if(s == 0){ printf("client quit! I should quit!\n"); break; }else{ perror("read"); } } close(fd); return 0; }
2、server端
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<errno.h> int main() { umask(0); if(mkfifo("./fifo",0666|S_IFIFO) < 0){ perror("mkfifo"); return 1;//shell look } int fd = open("./fifo",O_RDONLY); if(fd < 0){ perror("open"); return 2; } char buf[128]; while(1){ ssize_t s = read(fd,buf,sizeof(buf)); if(s > 0){ buf[s] = '\0'; printf("client# %s\n",buf); }else if(s == 0){ printf("client quit! I should quit!\n"); break; }else{ perror("read"); } } close(fd); return 0; }
client端输入什么,server端输出什么,结果如下所示:
相关文章推荐
- Linux匿名管道和命名管道模拟实现
- Linux进程间通信-匿名管道和与命名管道
- 【Linux】进程间通信(IPC)之匿名管道和命名管道以及测试用例
- linux 匿名、命名管道的实现
- Linux进程通信之管道(匿名,命名)
- 【Linux/OS/Network】匿名管道(pipe)和命名管道(FIFO)
- linux中的匿名管道和命名管道
- Linux-进程间通信(一、匿名管道与命名管道)
- linux学习---linux基于文件的IPC(匿名管道pipe,命名管道mkfifo,普通文件,socket文件)
- Linux--进程间通信之匿名管道及命名管道
- Linux匿名管道与命名管道
- 二十一、Linux系统编程-管道(二)命名管道(FIFO)、匿名管道与命名管道区别、命名管道的打开规则
- linux进程间通信:匿名管道和命名管道
- linux进程间通信方式之匿名管道
- 用QSocket来操作Linux命名管道
- Linux环境进程间通信(一)——管道(pipe)和命名管道(fifo)
- Linux下进程间通信:命名管道-mkfifo
- Linux中的pipe与named pipe(FIFO),即管道和命名管道
- 匿名和命名管道(windows)
- Linux下的IPC-命名管道的使用