fcntl实现对文件加锁功能

之前有一篇文章详细介绍了fcntl的用法,这一节将说明使用fcntl实现对文件加锁的功能,

fcntl函数原型

fcntl函数如下,具体用法可参考上面的文章。

1
2
#include <fcntl.h>
int fcntl(int fd, int cmd, .../*int args or lock args*/);

使用fcntl对文件加锁

当fcntl中的cmd为F_GETLK,F_SETLK,F_SELFKW时为对文件进行锁操作,此时arg参数为flock。注意:使用fcntl对文件加锁,加锁效果类似于自旋锁,只有写写互斥和读写互斥,读读并不互斥。

cmd取值及其操作

  • F_GETLK : 获取当前锁得状态
  • F_SETLK : 给当前文件上锁(非阻塞)。
  • F_SETLKW : 给当前文件上锁(阻塞,若当前文件正在被锁住,该函数一直阻塞)。

flock结构体定义如下:

1
2
3
4
5
6
7
8
struct flock {
short int l_type;
short int l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};

下面对flock中的参数一一解释:

  • l_type:此参数表示所得类型。其可能的取值包括一下三个:
    • F_RDLCK : 读锁
    • F_WRLCK : 写锁
    • F_UNLCK : 无锁状态
  • l_start : 此参数锁区域的开始位置的偏移量
  • l_whence:此参数决定锁开始的位置。其可选参数为:
    • SEEK_SET:当前位置为文件的开头
    • SEEK_CUR:当前位置为文件指针的位置
    • SEEK_END:当前位置为文件末尾
  • l_len : 锁定文件的长度

若要锁定整个文件,通常的方法为将l_start设为0,l_whence设为SEEK_SET,l_len设为0.

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void lock_set(int fd, int type) {
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
while (1) {
lock.l_type = type;
if ((fcntl(fd, F_SETLK, &lock)) == 0) {
if (lock.l_type == F_RDLCK)
printf("read lock set by %d\n", getpid());
else if(lock.l_type == F_WRLCK)
printf("write lock set by %d\n", getpid());
else if (lock.l_type == F_UNLCK)
printf("release lock by %d\n", getpid());
return;
}
//检查文件是否可以上锁
fcntl(fd, F_GETLK, &lock);
//判断不能上锁的原因
if (lock.l_type != F_UNLCK) {
if (lock.l_type == F_RDLCK)
printf("read lock has been already set by %d\n", getpid());
else if (lock.l_type == F_WRLCK)
printf("write lock has been already set by %d\n", getpid());
getchar();
}
}
}
int main() {
int fd;
fd = open("data", O_RDWR | O_CREAT, 0666);
if (fd < 0) {
perror("open failed");
return -1;
}
lock_set(fd, F_WRLCK);
getchar();
lock_set(fd, F_UNLCK);
getchar();
close(fd);
return 0;
}

Comment and share

  • page 1 of 1

魏传柳(2824759538@qq.com)

author.bio


Tencent


ShenZhen,China