函数sync、fsync、fdatasync以及fcntl

1,延迟写

        传统的UNIX系统实现在内核都设有缓冲区【高速缓存、页高速缓存】,大多数磁盘IO都是通过缓冲区进行。当我们向文件写入数据时,内核通常先将数据复制到缓冲区中,然后排入队列,晚些时候在写入磁盘。这种方式称为延迟写。

        为保证磁盘实际内容,与缓冲区的内容一致性,unix系统提供了sync、fsync、fdatasync函数

2,函数

#include <unistd.h>


void sync();


int fsync(int fd);
int fdatasync(int fd);
  
    return: 
        0:success
        -1: ERROR

sync() :只是将修改过的块缓冲区排入队列,然后返回,不等待实际的write磁盘操作结束,排入队列后,update守护进程每隔30s进行flush缓冲区,写磁盘。

fsync():只对由文件描述符fd指定的一个文件起作用,并且等待写磁盘操作结束后返回。

fdatasync():类似于fsync函数,但是只影响文件的数据部分,而除数据外,fsync还会同时更新文件的属性。

3、fcntl()函数

int fcntl(int fd, int cmd, /*int arg*/);
    功能:改变打开文件的属性
        复制一个已有的描述符   cmd = F_DUPFD  /  F_DUPFD_CLOEXEC
        获取、设置 文件描述符标志 cmd = F_GETFD   / F_SETFD
        获取、设置文件状态标志  cmd = F_GETFL / F_SETFL
        获取异步I/O所有权  cmd =  F_GETOWN  / F_SETOWN
        获取、设置记录锁  cmd = F_GETLK  / F_SETLK

解释各选项:

F_DUPFD:

        赋值文件描述符,新文件描述符作为函数返回值(最小且未打开的文件描述符值),他们共享同一个文件表项,但 新描述符有一套自己的文件描述符标志,其FD_CLOEXEC标志被清除

F_GETFD:

         获取fd文件描述符标志

F_GETFL :

        获取fd的文件状态标志(O_RDONLY、O_RWONLY、O_RDWR、O_APPREN、O_SYNC、O_NONBLOCK等)

F_GETOWN:

        获取但却接收SIGIO和SIGURG信号的进程ID

fcntl 返回值跟cmd有关:

        如果出错,返回:-1

        F_DUPFD:换回一个新的文件描述符

        FD_GETFD、FD_GETFL:返回相应的fd标志

        FD_GETOWN :返回一个进程ID

实例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

//测试文件描述符状态标志
int main(int argc, char *argv[])
{
        if(argc != 2)
        {
                printf("./a,out fd");
                return -1;
        }


        int val = fcntl( atoi(argv[1]), F_GETFL, 0 );
        if(val < 0)
        {
                perror("fcntl:");
                return -1;
        }
        switch(val & O_ACCMODE)
        {
                case O_RDONLY:
                        printf("Read\n");
                break;
                case O_WRONLY:
                        printf("Write\n");
                break;
                case O_RDWR:
                        printf("Read_Write\n");
                break;
                default:
                        printf("GET FL  is error\n");
                        break;
        }

        if(val & O_APPEND)
                printf("Apprend.");
        if(val & O_NONBLOCK)
                printf("NonbLock.");
        if(val & O_SYNC)
                printf("SYNC");

        printf("\n");
        return 0;
}

注:

        当使用F_SETFL时,不能去修改一个文件的打开方式(O_RDONLY/O_WRONLY/O_RDWR),如下部分代码:

//只读打开
int fd = open("./1.txt",O_RDONLY);
if(fd < 0)
{
    printf("open is error\n");
    return -1;
}

//get fd stat
int val= fcntl( fd, F_GETFL, 0);
if(val > 0)
{
   val |= O_RDWR;
   fcntl(fd, F_SETFL, val);
   perror("fcntl_1:");
}

//尝试写文件
if( 0 > write(fd ,"AAAAAAA",  7))
{
    perror("write :");
    return -1;
}

结果:

        fcntl_1:: Success
        write:: Bad file descriptor
(前面以为是自己SET状态时出错,后面尝试将文件打开方式改为O_RDWR,write函数成功写入)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值