Linux 文件I/O(三)之fcntl记录锁

Linux 文件I/O(三)之fcntl记录锁

      上篇已经介绍了fcntl的部分用法,现在我们重点看一下fcntl函数的文件锁功能!

函数原型

    int fcntl(int fd, int cmd, ... /* arg */ )

返回值

    获得/设置记录锁的功能,成功则返回0,若有错误则返回-1,错误原因存于errno。

参数

    在介绍参数之前先讲一下有助理解的一些知识。

结构体flock的指针:
struct flcok 
{ 
short int l_type; /* 锁定的状态*/
//以下的三个参数用于分段对文件加锁,若对整个文件加锁,则:l_whence=SEEK_SET, l_start=0, l_len=0
short int l_whence; /*决定l_start位置*/ 
off_t l_start; /*锁定区域的开头位置*/ 
off_t l_len; /*锁定区域的大小*/
pid_t l_pid; /*锁定动作的进程*/ 
};

l_type 有三种状态:
F_RDLCK   建立一个供读取用的锁定 
F_WRLCK   建立一个供写入用的锁定 
F_UNLCK   删除之前建立的锁定
l_whence 也有三种方式:
SEEK_SET   以文件开头为锁定的起始位置 
SEEK_CUR   以目前文件读写位置为锁定的起始位置 
SEEK_END   以文件结尾为锁定的起始位置

    文件锁包括建议性锁和强制性锁。一般情况下,内核和系统都不适用建议性锁,采用强制性锁的影响很大,每次读写操作都必须检查是否有锁存在。实现文件上锁的函数有lockf() 和fcntl() ,其中lockf()用于对文件施加建议性锁,而fcntl() 不仅可以施加建议性锁,而且可以施加强制性锁。fcntl()还能对文件的某一记录上锁,也就是记录锁。记录锁又可分读取锁(共享锁)和写入锁(排斥锁),文件的同一部分不能同时建立读取锁和写入锁。
    共享锁:你可以加共享锁,它也可以加,若干进程读的时候他们互不影响,设立共享锁的目的是避免该锁定区域被其它进程独占。但是共享锁并不是read-only只读的!其它进程如果有此文件的写权限,那么它仍然可以对此区域进行写操作。
    写入锁:如果用户申请了一个互斥锁定,其他进程都无法对该文件进行锁定。
    举个例子:进程A对某文件一部分设置了共享锁,进程B也可以对该部分设置共享锁,但不能设置写入锁。进程A对某文件的一部分设置了写入锁,其它进程不能再对该部分设置锁。

F_SETLK:
   这个命令用来实施 “锁定” 或 “解锁” 动作( 由文件描述符指定文件 )。flock 结构中的值( 不同于从F_GETLK 中的值) 如下:
l_type 
l_pid (未用)
l_type 有三个值:
F_RDLCK : 共享锁,只读用
F_WRLCK : 独占锁(写操作锁)
F_UNLCK : 解除锁定
    和 F_GETLK 一样,区域锁定同样用 l_start, l_whence 和 l_len 这三个值( 在 flock 结构体中 )来定义。如果锁操作成功,fcntl() 返回一个值( 执行了马上就能返回 ),否则返回 -1 。

F_SETLKW:
    F_SETLKW 的作用和上面的 F_SETLK 一样,不同的是如果无法锁定那它就会一直等待直到可以锁定为止;一旦进入等待状态,则这个函数只有在被可以进行锁定或者是接收到信号时才会返回。
    
   测试代码就先不写啦!
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux文件I/O操作可以使用系统调用来实现。其中,常用的系统调用有open、read、write、close等。 open是打开文件的系统调用,可以指定文件的路径、打开模式等参数。例如,打开一个文件并返回一个文件描述符的代码如下: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; fd = open("test.txt", O_RDONLY); if(fd == -1) { perror("open"); return 1; } printf("File descriptor: %d\n", fd); return 0; } ``` read是读取文件的系统调用,可以指定读取的文件描述符、缓冲区地址、读取的字节数等参数。例如,读取一个文件并输出其内容的代码如下: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #define BUF_SIZE 1024 int main() { int fd, n; char buf[BUF_SIZE]; fd = open("test.txt", O_RDONLY); if(fd == -1) { perror("open"); return 1; } while((n = read(fd, buf, BUF_SIZE)) > 0) { write(STDOUT_FILENO, buf, n); } close(fd); return 0; } ``` write是写入文件的系统调用,可以指定写入的文件描述符、缓冲区地址、写入的字节数等参数。例如,将用户输入的内容写入一个文件的代码如下: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #define BUF_SIZE 1024 int main() { int fd, n; char buf[BUF_SIZE]; fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if(fd == -1) { perror("open"); return 1; } while((n = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) { write(fd, buf, n); } close(fd); return 0; } ``` close是关闭文件的系统调用,可以指定要关闭的文件描述符。例如,关闭一个文件的代码如下: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; fd = open("test.txt", O_RDONLY); if(fd == -1) { perror("open"); return 1; } // do something close(fd); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值