在C语言中,flock
是一个用于文件锁定的函数,定义在 sys/file.h
头文件中。它的主要目的是在对文件进行读写操作时,避免其他进程同时访问文件,以实现文件的并发控制。
flock
函数的原型
#include <sys/file.h>
int flock(int fd, int operation);
参数
fd
: 文件描述符,通常通过open
函数获得。operation
: 锁定操作的类型,通常是以下几种之一:LOCK_SH
: 共享锁,允许其他进程读取文件,但不允许写入。LOCK_EX
: 排他锁,阻止其他进程读取或写入文件。LOCK_UN
: 解锁,释放之前的锁。LOCK_NB
: 非阻塞模式,锁定操作不会被阻塞,如果锁定失败,flock
立即返回错误。
返回值
- 成功:返回
0
。 - 失败:返回
-1
,并设置errno
以指示错误原因。
示例
进程A1写入完成前,进程A2的写入被阻塞,进程A3的读取被阻塞。
A1.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
perror("open");
exit(EXIT_FAILURE);
}
// 加锁
if (flock(fd, LOCK_EX) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
printf("File is locked. Performing operations...\n");
const char *message = "Hello, World!\n"; // 要写入的数据
// 写入数据
ssize_t bytesWritten = write(fd, message, strlen(message));
if (bytesWritten < 0) {
perror("write");
close(fd);
exit(EXIT_FAILURE);
} else {
printf("Successfully wrote %ld bytes to the file.\n", bytesWritten);
}
sleep(10);
// 简化写入过程不做成功判断 仅测试用
const char *endmsg = "The End!\n";
write(fd, endmsg, strlen(endmsg));
printf("writing finished\n");
// 解锁
if (flock(fd, LOCK_UN) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
close(fd);
return 0;
}
A2.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
perror("open");
exit(EXIT_FAILURE);
}
// 加锁
if (flock(fd, LOCK_EX) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
// 简化写入过程不做成功判断 仅测试用
const char *newmsg = "new msg!\n";
write(fd, newmsg, strlen(newmsg));
// 解锁
if (flock(fd, LOCK_UN) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
close(fd);
return 0;
}
A3.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#define BUFFER_SIZE 256
int main() {
// 打开文件以只读模式
int fd = open("example.txt", O_RDONLY);
if (fd < 0) {
perror("open");
exit(EXIT_FAILURE);
}
// 获取共享锁
if (flock(fd, LOCK_SH) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
// 读取数据
char buffer[BUFFER_SIZE];
ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
if (bytesRead < 0) {
perror("read");
flock(fd, LOCK_UN); // 解锁
close(fd);
exit(EXIT_FAILURE);
}
// 读取到的数据添加终止符
buffer[bytesRead] = '\0';
// 输出读取的数据
printf("Read from file: %s\n", buffer);
// 解锁
if (flock(fd, LOCK_UN) < 0) {
perror("flock");
close(fd);
exit(EXIT_FAILURE);
}
// 关闭文件
close(fd);
return 0;
}