(read默认是阻塞的,会一直等着,直到读到,所以会打印)
实现 ps aux | grep bash
#include <stdio.h> #include <unistd.h> int main() { int fd[2]; pipe(fd); pid_t pid = fork(); if(pid == 0){ //son //son -- > ps //关闭 读端 close(fd[0]); //1. 先重定向 dup2(fd[1],STDOUT_FILENO);//标准输出重定向到管道写端 //2. execlp execlp("ps","ps","aux",NULL); }else if(pid > 0){ //parent //关闭写端 close(fd[1]); //1. 先重定向,标准输入重定向到管道读端 dup2(fd[0],STDIN_FILENO); //2. execlp execlp("grep","grep","bash",NULL); } return 0; }
兄弟进程间通信,实现 ps aux | grep bash
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { int fd[2]; pipe(fd); pid_t pid; int n =2,i = 0; for(i = 0; i < n ; i ++){ pid = fork(); if(pid == 0){ break; } } //i = 0 ,代表兄长,1 - 代表弟弟,2- 父亲 if(i == 0){ //兄长进程 //1. 关闭读端 close(fd[0]); //2. 重定向 dup2(fd[1],STDOUT_FILENO); //3. 执行 execlp execlp("ps","ps","aux",NULL); }else if(i == 1){ //弟弟 //1. 关闭写端 close(fd[1]); //2. 重定向 dup2(fd[0],STDIN_FILENO); //3. 执行ececlp execlp("grep","grep","bash",NULL); }else if(i == 2){ //parent //父亲需要关闭读写两端 close(fd[0]); close(fd[1]); //回收子进程 wait(NULL); wait(NULL); } return 0; }
FiFO
写端:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> int main(int argc,char * argv[]) { if(argc != 2){ printf("./a.out fifoname "); return -1; } // 当前目录有一个 myfifo 文件 //打开fifo文件 printf("begin open .... "); int fd = open(argv[1],O_WRONLY); printf("end open .... "); //写 char buf[256]; int num = 1; while(1){ memset(buf,0x00,sizeof(buf)); sprintf(buf,"xiaoming%04d",num++); write(fd,buf,strlen(buf)); sleep(1); //循环写 } //关闭描述符 close(fd); return 0; }
读端:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> int main(int argc,char *argv[]) { if(argc != 2){ printf("./a.out fifoname "); return -1; } printf("begin oepn read... "); int fd = open(argv[1],O_RDONLY); printf("end oepn read... "); char buf[256]; int ret; while(1){ //循环读 memset(buf,0x00,sizeof(buf)); ret = read(fd,buf,sizeof(buf)); if(ret > 0){ printf("read:%s ",buf); } } close(fd); return 0; }
mmap
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <string.h> int main() { int fd = open("mem.txt",O_RDWR);//创建并且截断文件 //int fd = open("mem.txt",O_RDWR|O_CREAT|O_TRUNC,0664);//创建并且截断文件 ftruncate(fd,8); //创建映射区 char *mem = mmap(NULL,20,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); //文件只有8,此处20,也只会写8个 //char *mem = mmap(NULL,8,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0); //private 不会更改源文件 if(mem == MAP_FAILED){ perror("mmap err"); return -1; } close(fd); //拷贝数据 strcpy(mem,"helloworld"); // mem++; 若更改地址,munmap会报错 //释放mmap if(munmap(mem,20) < 0){ perror("munmap err"); } return 0; }
匿名映射无法实现无血缘关系进程间通信!
无血缘例子
写:
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> typedef struct _Student{ int sid; char sname[20]; }Student; int main(int argc, char* argv[]){ if(argc!=2){ printf("need filename "); return -1; } int fd=open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666); int length=sizeof(Student); ftruncate(fd,length); Student* stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(stu==MAP_FAILED){ perror("mmp err"); return -1; } int num=1; while(1){ stu->sid=num; sprintf(stu->sname,"xiaoming-%03d",num++); sleep(1); } munmap(stu,length); close(fd); return 0; }
读:
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> typedef struct _Student{ int sid; char sname[20]; }Student; int main(int argc, char* argv[]){ int fd=open(argv[1],O_RDWR); int length=sizeof(Student); Student* stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(stu==MAP_FAILED){ perror("mmap err"); return -1; } while(1){ printf("sid=%d, sname=%s ", stu->sid, stu->sname); sleep(1); } munmap(stu,length); close(fd); return 0; }
(文件作为媒介)
多进程拷贝文件:
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char* argv[]) { int n=5; if(argc<3){ printf("need file name "); return -1; } int srcfd=open(argv[1],O_RDONLY); if(srcfd<0){ perror("open err"); exit(1); } int dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664); if(dstfd<0){ perror("open err"); exit(1); } struct stat sb; stat(argv[1], &sb); int len=sb.st_size; truncate(argv[2],len); char *psrc=mmap(NULL,len,PROT_READ,MAP_SHARED,srcfd,0); if(psrc==MAP_FAILED){ perror("mmap src err"); exit(1); } char *pdst=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,dstfd,0); if(pdst==MAP_FAILED){ perror("mmap dst err"); exit(1); } int i=0; for(i=0;i<n;i++){ pid_t pid=fork(); if(pid==0) break; } int cpsize=len/n; int mod=len%n; if(i<n){ if(i==n-1){ memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize+mod); } else{ memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize); } }else{ int i=0; for(i=0;i<n;i++){ wait(NULL); } if(munmap(psrc,len)<0){ perror("munmap src err"); exit(1); } if(munmap(pdst,len)<0){ perror("munmap dst err"); exit(1); } close(srcfd); close(dstfd); } return 0; }