fwrite的理解。

测试过a+的时候,发现两个进程同时开一个文件,

1,即使不fclose,数据还是会往硬盘写。

2,发现1K的时候数据会从clib写入系统的PAGE_BUF.

3,从page_buf往硬盘写的时机是kernel有一个pflush线程按照一定的算法去刷新。

比如几个扇区挨的近的会在一起刷。

 

两个进程同时运行写一个文件,他们会穿插着写,而且穿插单位是1K。

include "stdio.h"
main()
{
        FILE *fp;
        int i=0;
        char buf[256]="hit33333\n";
        fp=fopen("./writefile.txt","a+");

        while(1)
        {
                i++;
                fwrite(buf,1,256,fp);
                sleep(1);
                printf("i si %d\n",i);
                if(i==600)
                        break;
        }
        fclose(fp);
}

 

 

include "stdio.h"
main()
{
        FILE *fp;
        int i=0;
        char buf[256]="love33333\n";
        fp=fopen("./writefile.txt","a+");

        while(1)
        {
                i++;
                fwrite(buf,1,256,fp);
                sleep(1);
                printf("j si %d\n",i);
                if(i==600)
                        break;
        }
        fclose(fp);
}

 

会发现打印是两个进程穿插。比如 i is 1,j is 1,i is 2 ,j is 2.

但是写入flash的数据是hit33333

                              hit33333

                              hit33333

                              hit33333

                              love3333

                              love3333

                              love3333

                              love3333

交替。

而且PAGE BUf是每4K刷一次!!!

文件大小上是每4K变一次。

如果加了fflush();

则PAGE BUF则是每次都会到设备。

从网络上有的说只会写到内核缓冲器。是fsync才会写到设备。

但是从fflush()测试的结果看,每次这个文件都是8字节增长,而且在不同进程中读,则发现是实时更新。

如果没有fflush,则是每4K才更新,导致另外一个进程的读会一开始都是空的。不同步。

这也说明一个问题,一个文件在内核中,当都是追加写的时候,用了同一个内核心缓冲,但是读的时候,是另一个缓冲,如果要按照顺序写,该如何处理。

加flush.





同时测试如下:

main()
{
        FILE *  fd;
        struct stat sb;
        char buf[0x8000];
        fd=fopen("./testtext","wb+");
        fwrite(buf,4092,1,fd);
//        fseek(fd,0,SEEK_END);
//      ftell(fd);
//      fseek(fd,0,SEEK_SET);

// fread(buf2,4092,1,fd);
        if(stat("./testtext", &sb) == -1)
        {
                printf("error!!\n");
                return -1;
        }

        printf("the size is %d\n",sb.st_size);

sleep(10);
        fwrite(buf,1,5,fd);
//      fflush(fd);
//      sleep(10);
        if(stat("./testtext", &sb) == -1)
        {
                printf("error!!");
                return -1;
        }
        printf("the22 size is %d\n",sb.st_size);
}

答案是0,4096.

如果开了fseek(fd,0,SEEK_END);答案是4092,4096.

应该是内核区域并刷到了硬盘,但是内核数据还是在,等到再刷5个字节的时候,再次将所有数据都丢到硬盘。

测试过,第一次写的时候4K会全部丢进硬盘,但是第二次写一定要超过4K,比如4K+1,所以这里一定是5,如果是4,答案将是4092,4092.


如果开了ftell(fd);答案是4092,4092.

应该是从内核区域并刷到了硬盘.而且内核数据被清除了,所以再刷5个字节的时候,因为内核还只有5个,不会再丢到内核区域。


如果开了fread(fd,0,SEEK_END),则一定会写到硬盘。而且内核,和SEEK一个道理。



分析这些,主要原因还是为了同步。

从上面的分析可以看出。

如果两个线程一个读,一个写,则需要同步。两个写,也是必须同步。















 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值