• 系统编程-进程-先后fork或open一个文件的区别


    
    

    关联博文:

    当文件操作遇上fork

    Linux内核的文件结构体

    struct file {
        .........    
        struct path        f_path;            //文件的路径
    #define f_dentry    f_path.dentry
    #define f_vfsmnt    f_path.mnt
        const struct file_operations    *f_op;//访问方式
        atomic_long_t        f_count;        //文件的引用计数,引用计数值为0时,文件才会关闭
        unsigned int         f_flags;        //标志位
        mode_t            f_mode;            //读写等权限
        loff_t            f_pos;             //读到了哪个位置
        struct fown_struct    f_owner;
        unsigned int        f_uid, f_gid;   //文件所属uid,gid
        struct file_ra_state    f_ra;
    
        u64            f_version;
    #ifdef CONFIG_SECURITY
        void            *f_security;
    #endif
        /* needed for tty driver, and maybe others */
        void            *private_data;
        
        .............
    };

    文件的引用计数,引用计数值为0时,文件才会被关闭。

     

    两种情景分析:

    1.fork()之前就open了文件,并且读取了部分内容

    #include<stdio.h>
    #include<stdlib.h>
    #include<assert.h>
    #include<string.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<fcntl.h>
    
    int main()
    {
        int fd = open("tmp.txt",O_RDONLY);
        assert(fd!=-1);
    
        char buff[10]={0};
    
        pid_t pid = fork();
    
        if(pid == 0){
                read(fd,buff,1);  //子进程读1个字节内容
            printf("buff = %s
    ",buff);
    
        }else if(pid  > 0){
            sleep(5);         //保证子进程可以先读文件
            read(fd,buff,2);  //父进程读2个字节
            printf("buff = %s
    ",buff);
            wait(NULL);       //收尸,不获取死因
        }
        
        close(fd);
        return 0;    
    }

     tmp.txt的内容为“niceday”

    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# gcc process.c  -o ab
    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# 
    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# ./ab
    buff = n
    buff = ic

    小结:

    先open再fork,文件只被打开一次,父子进程共享一个文件描述信息,包括引用计数、读取位置等等。

    虽然父子进程都读取了该文件,由于文件的引用计数始终为1,所以只需要close一次即可。

    可以在子进程代码分支中close,也可以在父进程代码分支close,还可以在公共部分close。

    子进程复制了父进程的文件表项指针, 指向的是同一个文件表项,如下图:

     

     

    2.fork()调用之后open文件

    #include<stdio.h>
    #include<stdlib.h>
    #include<assert.h>
    #include<string.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<fcntl.h>
    
    int main()
    {
        pid_t pid = fork();
    
        int fd = open("tmp.txt",O_RDONLY);
        assert(fd!=-1);
    
        char buff[10]={0};
    
        if(pid == 0){
                read(fd,buff,1);  //子进程读1个字节内容
            printf("buff = %s
    ",buff);
    
        }else if(pid  > 0){
            sleep(5);         //保证子进程可以先读文件
            read(fd,buff,2);  //父进程读2个字节
            printf("buff = %s
    ",buff);
            wait(NULL);       //收尸,不获取死因
        }
        
        close(fd);
        return 0;    
    }

    tmp.txt的内容为“niceday”, 同上。

    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# gcc process.c  -o ab
    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# 
    root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# ./ab
    buff = n
    buff = ni

    小结:

    此时的文件描述信息不再是共享的,一个文件被打开了两次,即引用计数值为2,每个进程都有自己的一份,所以两个进程读写操作互不影响。

     

    总结:

    先open,再fork:子进程无条件继承父进程的文件描述信息,子进程和父进程指向同一个文件描述信息。
    先fork,再open:子进程有自己的配置,和父进程的配置是相互独立的关系。所谓配置,例如文件描述信息。

    文末,再来一幅图(不一样的精彩)

     

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    安装VCSA6.5(vCenter Server Appliance 6.5)
    VMware文章总结
    kbmmw 的远程桌面功能2-android手机端
    kbmmw 的远程桌面功能
    delphi 中的win32 以外到平台的字符串处理一定慢吗?(转载)
    delphi 中如何访问另一个类中到私有方法?(转载)
    使用 kbmmw 的ORM开发纯REST数据库访问服务
    kbmmw 5.05.00 发布
    使用delphi-cross-socket 开发kbmmw smart http service
    利用Delphi-cross-socket 库提升kbmmw 跨平台开发
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/13823641.html
Copyright © 2020-2023  润新知