• 进程间通信


    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
    ",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 ",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
    ",*mem);
                            sleep(3);
                    printf("child,*mem=%d
    ",*mem);
    
            }
            else if(pid>0)
            {
                    //父进程
                    sleep(1);
                    printf("parent,*mem=%d
    ",*mem);
                    *mem=1001;
                    printf("parent,*mem=%d
    ",*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 ",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
    ");
                    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;
    }
  • 相关阅读:
    浅析Vue3相关基础知识:Vue3应用配置、重写的vmodel、emits 选项、getCurrentInstance()获取实例、采用mitt实现全局通讯、vuerouter的新特性
    Vue3结合TS项目开发实践:Composition API的风格理念、关注点分离、如何组织TS进行项目开发(采用声明文件来管理接口及所需类型/目录结构推荐)
    TypeScript类型守卫、联合类型、交叉类型
    Android开发历程_14(广播机制)
    OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)
    OpenGL_Qt学习笔记之_06(纹理滤波、光照和色彩融合)
    Qt学习之路_12(简易数据管理系统)
    特征点检测学习_2(surf算法)
    Kinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像)
    PCA算法学习_1(OpenCV中PCA实现人脸降维)
  • 原文地址:https://www.cnblogs.com/sclu/p/11253367.html
Copyright © 2020-2023  润新知