大家好,又见面了,我是你们的老朋友全栈君。
在Linux系统中,软件和硬件资源都被视为文件(即“一切皆文件”)。在多用户环境下,这些文件是可以共享的。
文件锁是一种机制,用于解决多个用户共享文件时的资源竞争问题:当多个用户需要访问同一个文件时,Linux通常会通过对文件加锁来避免资源竞争。
文件锁分为建议性锁和强制性锁:
建议性锁:要求每个使用锁定文件的进程都必须检查是否已有锁存在,并且遵守已有锁的存在。通常,内核和系统不会强制执行建议性锁,而是依赖程序员遵守规则。
强制性锁:由内核执行。当文件被锁定用于写入时,内核将阻止其他任何对该文件的读写操作。强制性锁对系统性能有显著影响,因为每次读写操作都需要检查锁的存在。
在Linux中,实现文件锁的函数有lockf()和fcntl()。lockf()用于设置建议性锁,而fcntl()不仅能设置建议性锁,还能设置强制性锁。fcntl()还可以对文件的特定记录进行锁定,即记录锁。
记录锁分为读取锁和写入锁。读取锁又称共享锁,允许多个进程在文件的同一部分建立读取锁。写入锁又称排他锁,任何时刻只能有一个进程在文件的某个部分建立写入锁。同一文件部分不能同时存在读取锁和写入锁。
fcntl()函数的格式如下:
#include <sys/types.h> #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ...); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock);
fcntl()函数的参数包括:
fd:被操作的文件描述符。cmd:命令类型,包括:F_DUPFD:复制现有描述符。F_GETFD:获取fd的close-on-exec标志。F_SETFD:设置close-on-exec标志。F_GETFL:获取open设置的标志。F_SETFL:更改open设置的标志。F_GETLK:根据lock参数值,决定是否可以上文件锁。F_SETLK:设置lock参数值的文件锁。F_SETLKW:F_SETLK的阻塞版本。close_on_exec是一个进程所有文件描述符的位图标志,用于在调用execve()时决定哪些文件描述符需要关闭。
fcntl()函数的返回值取决于第二个参数cmd,成功时返回值不同,失败时返回-1。

fcntl()的使用实例:
首先为flock结构体的相应字段赋值,然后使用fcntl()函数两次,分别用于判断文件是否可以上锁和对文件上锁,使用的cmd值分别为F_GETLK和F_SETLK(或F_SETLKW)。使用F_GETLK命令判断是否可以进行flock结构所描述的锁操作:如果可以加锁,flock结构的l_type会被设置为F_UNLCK,其他域保持不变;否则,l_pid被设置为拥有文件锁的进程号,l_type被设置为已有锁的类型,其他域保持不变。
mylock.h:
int lock_set(int fd, int type) {
struct flock old_lock, lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = type;
lock.l_pid = -1;
fcntl(fd, F_GETLK, &lock);
if (lock.l_type != F_UNLCK) {
if (lock.l_type == F_RDLCK) {
printf("Read lock already set by %d\n", lock.l_pid);
} else if (lock.l_type == F_WRLCK) {
printf("Write lock already set by %d\n", lock.l_pid);
}
}
lock.l_type = type;
if ((fcntl(fd, F_SETLKW, &lock)) < 0) {
perror("fcntl");
exit(1);
}
return 0;
}write_lock.c:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include "mylock.h"
int main(void) {
int fd;
fd = open("hello", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
perror("open");
exit(1);
}
lock_set(fd, F_WRLCK);
printf("Write lock set\n");
sleep(20);
lock_set(fd, F_UNLCK);
close(fd);
return 0;
}

写入锁是互斥锁,同一时刻只能有一个写操作成功。
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include "mylock.h"
int main(void) {
int fd;
fd = open("hello", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
perror("open");
exit(1);
}
lock_set(fd, F_RDLCK);
printf("Read lock set\n");
sleep(20);
lock_set(fd, F_UNLCK);
close(fd);
return 0;
}
读锁是共享锁,允许多个进程同时读取文件。
参考资料:
https://www.php.cn/link/103c95b905e20d63a6354e5284922bd2
发布者:全栈程序员栈长,转载请注明出处:https://www.php.cn/link/89a183c0c11d6d0ca7830f9d530a3097
原文链接:https://www.php.cn/link/c8377ad2a50fb65de28b11cfc628d75c
以上就是linux 文件锁的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号