标题:关于open函数的内部问题
只看楼主
kingsroot
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:284
专家分:1159
注 册:2010-3-28
结帖率:66.67%
 问题点数:0 回复次数:4 
关于open函数的内部问题
  在Linux下(注意不是windows) 调用open会在内核中建立一个file结构,当然在task_struct(及PCB中)结构中,由一个file指针指向它,所有open是把内核中的文件file结构映射到用户空间中,用户空间就用文件描述符操作文件,但是当2个或者更多进程打开同一个文件或者在同一进程中重复打开一个文件,虽然也返回不同的文件描述符,但是文件描述符都是指向同一个file结构,唯一有变化的就是在file结构体中有个count(好象是,具体名字记不清除了)的字段会增加,以表示有多少进程在使用本文件;简单的说,如果用open以同一中方式打开同一个文件,在内核中都使用同一个file结构
可以参看以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
int main( void )
{
    int fd1, fd2;
    char str[10];
    fd1 = open( "test", O_CREAT | O_RDWR );//这里O_CREAT不是打开方式,只是告诉内核如果test不存在就建立,如果存在就忽略
    assert( fd1 != -1 );
    printf( "file Number is: %d\n", fd1 );
    fd2 = open( "test",  O_RDWR );
    assert( fd2 != -1 );
    printf( "file Number is: %d\n", fd2 );//这里验证返回了不一样的文件描述符
    write( fd2, "Hello", 5 );
    write( fd2, "pig", 3 );//这里我们用fd2写文件
    read( fd1, str , 8 ); //这里我们用fd1读文件
    str[9] = '\n';
    printf( "read file is :%s\n", str ); //这里输出的是Hellopig,可以验证虽然是2个不同的文件描述符,但是是使用的同一个file结构
    return 0;
}
以上代码是验证一个进程里2个不同open调用使用一个file结构程序

以下代码是不同2个进程打开同一个文件的实验
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
int main( void )
{
        int fd1;
        fd1 = open(  "test", O_CREAT | O_RDWR );
        assert( fd1 != -1 );
        write( fd1, "Hello,Pig", 9 );
        sleep( 20 );//这里睡秒20秒,主要是为了打开另外一个进程
        close( fd1 );
        return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
int main( void )
{
        int fd1;
        char str[10];
        fd1 = open(  "test", O_CREAT | O_RDWR );
        assert( fd1 != -1 );
        read( fd1, str, 9 );
        str[9] = '\n';
        printf( "%s\n", str );
        close( fd1 );
        return 0;
}
得出的结果是Hello,pig, 至此,完全证明了在用open打开文件时,如果打开文件的模式相同,则所有的文件描述符都是使用同一file的,所以像什么read,write之类的函数是线程不安全的  因为不可以重入  
另外,说点题外话,起始我们用write时,操作的是file结构提供的内核缓冲区,不要以为在用户空间哟~~~~~~~~~
强列要求斑竹给弄成精华帖  我还没有一篇贴是精华帖(虽然我一共才发2篇帖)
搜索更多相关主题的帖子: 函数 open 
2010-07-04 16:19
myhnuhai
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:3
帖 子:425
专家分:1725
注 册:2010-3-17
得分:0 
路过。

不要让肮脏的记忆,迷失了原本纯洁的心灵!
2010-07-04 17:36
zisefengye
Rank: 5Rank: 5
等 级:职业侠客
帖 子:167
专家分:386
注 册:2010-6-27
得分:0 
假如真这么做的话,的确很不安全。一般的做法是,第一个打开文件的程序,应该对打开的文件资源上锁,独占写锁,第二个打开的程序,只能读取文件,而不能修改。
2010-07-04 19:52
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
回复 楼主 kingsroot
open 还有第三个参数,注意了!

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-05 23:36
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:0 
我觉得楼主的实验也证明不了你说的东西呀。

比如我问几个问题,看看楼主怎么解释:
1,你说虽然文件描述符不同,但都是指向同一个 file 结构。为什么第一个演示实验中,两次用 fd2 写文件却没有使 fd1 的文件位置后移?(你显然没有用 lseek 回倒)
2,楼主说 file 中只(原话是唯一,我这么理解可以吧)纪录有多少进程在使用本文件。那么像实验一这样,_一个_进程打开了两遍同一个文件。如果我用它返回的不同的文件描述符关闭两次文件,由于系统无法发现这一区别,会不会出现错误?
3,楼主的实验如何说明系统在 read 和 write 的时候使用的缓存?
2010-08-06 04:40



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-312097-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019126 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved