golang父进程通过管道向子进程传递数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang父进程通过管道向子进程传递数据相关的知识,希望对你有一定的参考价值。
参考技术A golang父进程通过管道向子进程传递数据这里例子里面父进程launch一个子进程,然后通过管道(stdin)向子进程传递文本串。
父进程:
子进程:
进程间通信
IPC-进程间通信
一、管道
1、概念
2、pipe函数
2.1pipe介绍
2.2 pipe代码示例 父进程向子进程写数据
#include<stdio.h> #include<unistd.h> int main() pid_t pid; int pfd[2]; //定义两个文件描述符,放在数组中 int ret=pipe(pfd); //定义管道 if(ret==-1) perror("pipe error:"); exit(1); pid=fork(); if(pid==-1) perror("fork error:"); exit(1); else if(pid==0) close(pfd[1]); //关闭子进程写端口 char buf[1024]=0; int ret=read(pfd[0],buf,sizeof(buf)); //从管道读数据 write(STDOUT_FILENO,buf,ret); else close(pfd[0]); //关闭父进程读端口 write(pfd[1],"hello world\\n",sizeof("hello world")); //向管道写数据 return 0;
2.3管道读写行为
2.4管道优劣
2.5 FIFO(有名管道)
2.5.1 FIFO概念
2.5.2实现FIFO进程通信,可以实现无血缘关的进程通信
//写端程序 #include<stdio.h> #include<unistd.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #include<string.h> int main() //当前目录有一个myfifo文件 //打开fifo文件 int fd=open("myfifo",O_WRONLY); //写 char buf[256]=0; int num=1; while(1) memset(buf,0x00,sizeof(buf)); sprintf(buf,"newdata%d",num++); write(fd,buf,sizeof(buf)); sleep(1); //循环写 //关闭描述符 close(fd); return 0;
//读端程序
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<string.h> #include<unistd.h> #include<fcntl.h> int main() int fd=open("myfifo",O_RDONLY); char buf[256]=0; int ret; while(1) ret=read(fd,buf,sizeof(buf)); if(ret>0) printf("%s\\n",buf); close(fd); return 0;
二、共享存储映射
1.创建内存映射
2.释放映射区
3.代码示例 通过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); //创建映射 char *mem=mmap(NULL,8,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); //PRIVATE 不修改文件 //char *mem=mmap(NULL,8,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0); if(mem==MAP_FAILED) perror("mmap error"); return 0; //拷贝数据 strcpy(mem,"i am you"); //释放mmap munmap(mem,8); close(fd); return 0;
4.mmap注意事项
5.mmap实现父子进程间通信
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/wait.h> int main() //创建映射区 int fd=open("mem.txt",O_RDWR); int *mem=mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(mem==MAP_FAILED) perror("mmap error:"); return 0; //fork子进程 pid_t pid=fork(); //父进程和子进程交替修改数据 if(pid==0) //子进程 *mem=100; printf("child,*mem=%d\\n",*mem); sleep(3); printf("child,*mem=%d\\n",*mem); else if(pid>0) //父进程 sleep(1); printf("parent,*mem=%d\\n",*mem); *mem=1001; printf("parent,*mem=%d\\n",*mem); wait(NULL); munmap(mem,4); close(fd); return 0;
6.匿名映射(有血缘关系)
通过MAP_ANON和MAP_ANONYMOUS
int *mem=mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
7.mmap实现无血缘关系进程通信
//读端 #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<sys/mman.h> typedef struct Student int sid; char sname[20]; Student; int main(int argc,char *argv[])
if(argc!=2)
printf("./a.out filename");
return 0;
//open file int fd=open(argv[1],O_RDWR); //mmap int length=sizeof(Student); Student * stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(stu==MAP_FAILED) printf("map err:"); return 0; //read data while(1) printf("sid = %d, sname = %s \\n",stu->sid,stu->sname); sleep(1); munmap(stu,length); close(fd); return 0;
//写端 #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<sys/mman.h> typedef struct Student int sid; char sname[20]; Student; int main(int argc,char* argv[]) if(argc!=2) printf("./a.out filename\\n"); return 0; //1.open file int fd=open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666); int length=sizeof(Student); int num=1; ftruncate(fd,sizeof(length)); //2.mmap Student * stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(stu==MAP_FAILED) printf("mmap err:"); return 0; //3.修改内存数据 while(1) stu->sid=num; sprintf(stu->sname,"xiaoming-%03d",num++); sleep(1); //4.释放映射区 关闭文件 munmap(stu,length); close(fd); return 0;
以上是关于golang父进程通过管道向子进程传递数据的主要内容,如果未能解决你的问题,请参考以下文章