在 fcntl
函数中使用 struct flock
结构体进行文件锁定时,l_whence
成员用于指定文件锁操作的起始位置。它定义了文件锁的偏移量是相对于哪个位置的。l_whence
有以下几种可能的值,每种值的含义如下:
l_whence
的可能值及其含义
-
SEEK_SET
:- 含义: 文件偏移量是从文件的开头开始计算的。
- 用途: 当
l_whence
设置为SEEK_SET
时,l_start
的值是从文件开头的绝对位置。如果你想要锁定文件的某个绝对位置到指定的长度,可以使用这个值。
-
SEEK_CUR
:- 含义: 文件偏移量是从当前文件位置开始计算的。
- 用途: 当
l_whence
设置为SEEK_CUR
时,l_start
的值是相对于当前文件位置的偏移量。这适用于需要锁定从当前文件指针位置开始的区域。
-
SEEK_END
:- 含义: 文件偏移量是从文件末尾开始计算的。
- 用途: 当
l_whence
设置为SEEK_END
时,l_start
的值是相对于文件末尾的偏移量。这在需要锁定文件末尾的部分时很有用,例如在处理日志文件时。
使用 SEEK_SET
在示例代码中,l_whence
被设置为 SEEK_SET
:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#define BUF_LEN 4096
int main(int argc, char *argv[]) {
int ret = 0;
struct flock test_lock = { // 定义一个 flock 结构体用于文件锁操作
.l_whence = SEEK_SET, // 文件锁的起始位置设置为文件开始处
.l_type = F_WRLCK // 设置文件锁为写锁(排他锁)
};
int fd = open("test.bin", O_RDWR);
if (fd < 0) {
printf("open file failed\n");
return 1;
}
printf("before lock file\n");
ret = fcntl(fd, F_SETLKW, &test_lock);
if (ret < 0) {
printf("lock file failed\n");
close(fd);
return 1;
}
printf("after lock file\n");
sleep(150); // 休眠150秒,用于模拟文件被锁定状态下的访问碰撞
close(fd);
return 0;
}
这表示锁定的起始位置是从文件开头计算的,锁定区域的起点由 l_start
指定。
使用 SEEK_CUR
如果你使用的是 SEEK_CUR
,锁定区域的起点将相对于当前文件指针位置进行计算。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDWR);
if (fd < 0) {
perror("open failed");
return 1;
}
struct flock lock;
lock.l_type = F_WRLCK; // 写锁
lock.l_whence = SEEK_CUR; // 相对于当前文件位置
lock.l_start = 10; // 从当前文件位置偏移10字节开始锁定
lock.l_len = 20; // 锁定20字节
if (fcntl(fd, F_SETLKW, &lock) < 0) {
perror("fcntl failed");
close(fd);
return 1;
}
printf("Locked 20 bytes starting 10 bytes from the current position.\n");
// 进行一些操作...
close(fd);
return 0;
}
使用 SEEK_END
如果你使用的是SEEK_END
,锁定区域的起点将相对于文件末尾的位置进行计算。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDWR);
if (fd < 0) {
perror("open failed");
return 1;
}
struct flock lock;
lock.l_type = F_WRLCK; // 写锁
lock.l_whence = SEEK_END; // 相对于文件末尾
lock.l_start = -20; // 从文件末尾向回偏移20字节开始锁定
lock.l_len = 20; // 锁定20字节
if (fcntl(fd, F_SETLKW, &lock) < 0) {
perror("fcntl failed");
close(fd);
return 1;
}
printf("Locked 20 bytes ending at the file end.\n");
// 进行一些操作...
close(fd);
return 0;
}
总结
-
SEEK_SET
: 锁定区域相对于文件开头。用于锁定文件的某个绝对位置到指定的长度。 -
SEEK_CUR
: 锁定区域相对于当前文件位置。用于在文件当前位置基础上进行锁定。 -
SEEK_END
: 锁定区域相对于文件末尾。用于锁定文件的最后部分或倒数部分。