07,文件锁



文件锁/建议锁的由来

当两个进程在同一时刻向同一个文件中写入数据时,
可能造成数据的交错和不一致问题;

当一个进程在向文件写入数据的同时,
另外一个进程读取文件中数据时也可能造成数据的不一致问题;

当两个进程同时读取同一个文件数据时,可以同时进行;

为了实现上述表格的效果,linux系统中引入文件锁的机制,
文件锁本质上就是读写锁,一把读锁和一把写锁,
其中读锁是一把共享锁,允许其他进行加读锁,但不能加写锁;
写锁是一把排他锁,不允许其他进行加读锁/写锁
******************************************************
******************************************************

fcntl函数
#include <unistd.h>
 #include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

第一个参数:文件描述符,一般给open函数的返回值

第二个参数:具体的操作命令 - 主要用于实现建议锁功能

   F_SETLK:当锁的类型是F_RDLCK(读锁)或F_WRLCK(写锁)时实现加锁效果;
               F_UNLCK(解锁)时,实现解锁效果;
               具体的锁信息由该函数的第三个参数指定
               ***当文件上已经拥有冲突锁时,
               该函数调用失败,返回-1并设置errno的数值
   
   F_SETLKW:功能和F_SETLK类似,所不同的是当文件上已经拥有冲突锁信息时;
                该函数调用并不会返回失败,而是一直等待下去,直到文件上存在的
                锁被释放为止;
   
   F_GETLK:如果该锁能够被放在文件上,则不会真正放置上去;
               只是将锁的类型改为F_UNCLK,结构体其他的成员保持不变
               如果该锁不能被放置在文件上,则fcntl函数会用文件上
               已经存在的锁信息去替换第三个参数描述的锁信息,
               并将l_pid的数值设置为真正给文件加锁进程的进程号
               
               实际用途:判断当前文件受否有锁?!并且获取锁的信息
               
               

第三个参数:可变长参数,是否需要取决于cmd
   当实现建议锁功能时,该参数是一个指向以下结构体的指针,具体的结构体类型如下:

struct flock {
   ...
   short l_type;    /* 锁的类型: F_RDLCK(读锁),F_WRLCK(写锁), F_UNLCK(解锁) */
   short l_whence;  /* 锁定的起始位置:SEEK_SET, SEEK_CUR, SEEK_END */
   off_t l_start;   /* 相对于起始位置锁定的偏移量 */
   off_t l_len;     /* 锁定的字节数,也就是长度 */
   pid_t l_pid;     /* 加锁的进程号,默认给-1 (F_GETLK only) */
   ...
};

函数功能:
    主要用于对指定的文件描述符执行指定的操作;
    
返回值:-1,表示加锁失败!1.46



释放锁的主要方式:
1.将锁类型设置为F_UNLCK,使用fcntl函数调用即可;
2.使用close函数关闭文件描述符,与该描述符相关的文件锁全部被自动释放;
3.当进程结束时,与该进程相关的文件锁全部被释放;

******************************************************
******************************************************
******************************************************


#include <unistd.h>
int access(const char *pathname, int mode);    

第一个参数:字符串形式的文件路径名
第二个参数:具体操作模式
    F_OK:判断文件是否存在
    R_OK:判断文件是否可读
    W_OK:判断文件是否可写
    X_OK:判断文件是否可执行

成功返回0;失败返回-1

函数功能:主要用于检查文件的权限





*********文件管理:*********

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);

第一个参数:字符串类型的文件路径名/文件描述符
第二个参数:结构体指针,传递结构体变量的地址

函数功能:只要用于获取指定文件的状态信息;

成功返回0;失败返回-1

 struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* 文件的类型和权限 */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* 文件大小,单位:字节 */
               blksize_t st_blksize; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* 最后一次的修改时间 */
               time_t    st_ctime;   /* time of last status change */
           };



获取文件大小的方法:
a:调用fseek(),ftell();
b: 调用lseek();
b: 调用stat()/fstat();



#include <time.h>
char *ctime(const time_t *timep);
功能:主要用于将参数指定的整数时间转换成字符串类型时间



struct tm *localtime(const time_t *timep);
主功能:主要用于将参数指定的整数时间转换成结构体指针类型;
结构体类型如下:
struct tm {
    int tm_sec;         /* seconds */
    int tm_min;         /* minutes */
    int tm_hour;        /* hours */
    int tm_mday;        /* day of the month */
    int tm_mon;         /* month */
    int tm_year;        /* year + 1900 */
    int tm_wday;        /* day of the week */
    int tm_yday;        /* day in the year */
    int tm_isdst;       /* daylight saving time */
};





#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

第一个参数:字符串类型的文件路径名/文件描述符
第二个参数:重新设置的权限;比如:0664

功能:主要用于将指定文件的权限修改为指定的新权限

成功返回0;失败返回-1






#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

第一个参数:字符串类型的文件路径名/文件描述符
第二个参数:指定新的长度/大小

功能:主要用于修改指定文件的大小到指定的长度
    注意:如果文件的长度变小了,则多余的数据会产生丢失;
         如果文件的长度变大了,则扩展空间读到的数据是'\0'

成功返回0;失败返回-1





#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
第一个参数:建立映射的起始地址
第二个参赛:建立映射的长度
第三个参赛:映射的访问权限
    PROT_EXEC    可执行
    PROT_READ    可读
    PROT_WRITE    可写
    PROT_NONE    不可访问
    
第四个参赛:具体的操作标志,映射对文件是否有效
第五个参赛:文件描述符,默认0
第六个参数:文件中的偏移量,默认0

返回值:成功返回映射首地址,失败返回 MAP_FAILED
函数功能:
    主要用于建立文件/设备到虚拟地址的映射
    

int munmap(void *addr, size_t length);
第一个参数:映射区的首地址,mmap函数的返回值
第二个参数:映射区的大小
函数功能:
    主要用于解除参数指定的映射


主要用于建立/解除 文件/设备 到 虚拟地址的映射;
本质上就是把对文件的读写操作转换为对内存地址的操作,当有大量的数据进行读写操作时,
这种方式效率比read/write函数的方式高些





其他操作函数
umask():设置新文件在创建时要屏蔽的权限
link():创建硬链接
unlink():删除硬链接
rename():实现重命名的效果
remove():删除文件



**********目录的管理*********
opendir函数
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);

函数功能: 主要用于打开参数指定的目录,成功返回一个DIR类型的指针,失败返回NULL;



readdir函数
#include <dirent.h>
struct dirent *readdir(DIR *dirp);

函数功能:
    主要用于读取参数指定目录中的内容,成功返回一个结构体指针,失败返回NULL;
    该函数返回NULL有两种情况:一种是读到了目录的末尾,但是不会改变errno的数值;
    另一种是出现了错误,但是会设置errno的数值表达错误的原因;


struct dirent
{
   ... ...
   unsigned char  d_type;   /* 文件的类型 */
   char           d_name[256]; /* 文件的名称 */
};         

closedir函数
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);

函数功能:
   主要用于关闭参数指定的目录,参数为opendir函数的返回值;


其他目录操作函数
   mkdir() - 主要用于创建目录;
   rmdir() - 主要用于删除目录;
   chdir() - 主要用于切换目录;
   getcwd() - 主要用于获取当前工作目录的绝对路径;
   ... ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux VFS(Virtual File System)文件是用于在多进程或多线程环境下对文件进行并发访问控制的机制。它可以确保同一时间只有一个进程或线程能够对文件进行写操作,从而避免数据的不一致性和竞争条件的发生。 Linux VFS文件主要有两种类型:共享(读)和独占(写)。共享允许多个进程或线程同时对文件进行读操作,而独占则只允许一个进程或线程对文件进行写操作。 在Linux中,文件是通过fcntl系统调用来实现的。具体而言,可以使用fcntl函数来获取、设置和释放文件。fcntl函数的相关参数包括文件描述符、类型、起始位置和长度等。 以下是一些关于Linux VFS文件的常见问题及回答: 1. 什么是共享和独占? 共享(读)允许多个进程或线程同时对文件进行读操作,不会阻塞其他进程或线程的读操作。独占(写)则只允许一个进程或线程对文件进行写操作,其他进程或线程的读写操作都会被阻塞。 2. 如何获取文件? 可以使用fcntl函数来获取文件。通过设置fcntl函数的参数,可以指定类型、起始位置和长度等信息。 3. 文件的作用是什么? 文件可以确保同一时间只有一个进程或线程能够对文件进行写操作,从而避免数据的不一致性和竞争条件的发生。它在多进程或多线程环境下起到了并发访问控制的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值