lock.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <errno.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
/**
* @brief 尝试获取文件锁
* @details 获取文件锁时不会阻塞进程, 获取不到锁时,立即返回不会等待
* @param fd 文件描述符
* @return 是否成功获取文件锁
* @retval TRUE 获取锁成功
* @retval FALSE 获取锁失败
* @attention 这里只是建议性锁,每个使用上锁文件的进程都要检查是否有锁存在,
* 内核不对读写操作做内部检查和强制保护
*/
int trylock_fd(int fd)
{
if (flock(fd, LOCK_EX|LOCK_NB) == 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
* @brief 获取锁或等待
* @details 获取文件锁时会阻塞进程, 获取不到锁时,一直等到获取成功
* @param fd 文件描述符
* @return 是否成功获取文件锁
* @retval TRUE 获取锁成功
* @retval FALSE 获取锁失败
* @attention 这里只是建议性锁,每个使用上锁文件的进程都要检查是否有锁存在,
* 内核不对读写操作做内部检查和强制保护
*/
int waitlock_fd(int fd)
{
if (flock(fd, LOCK_EX) == 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
* @brief 释放文件锁
* @param fd 文件描述符
* @return 是否成功释放文件锁
* @retval TRUE 释放锁成功
* @retval FALSE 释放锁失败
*/
int unlock_fd(int fd)
{
if (flock(fd, LOCK_UN) == 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
* @brief 主函数
* @details 测试获取锁、释放锁的函数
* @param argc 命令参数个数
* @param argv 命令参数指针数组
* @return 程序执行成功与否
* @retval 0 程序执行成功
* @retval 1 程序执行失败
*/
int main(int argc, char *argv[])
{
int fd;
char *file;
pid_t pid;
if (argc == 2) {
file = argv[1];
} else {
file = "file.lock";
}
pid = getpid();
fd = open(file, O_RDWR|O_CREAT, 0666);
if (fd < 0) {
fprintf(stderr, "failed to open \"%s\", detail: %s(%d)\n",
file, strerror(errno), errno);
exit(1);
}
if(trylock_fd(fd)) {
printf("file has been locked by %d. press any key to unlock\n", pid);
} else {
printf("waiting for lock\n");
waitlock_fd(fd);
printf("file has been locked by %d. press any key to unlock\n", pid);
}
getchar();
unlock_fd(fd);
printf("file has been unlocked by %d.\n", pid);
close(fd);
exit(0);
}
Makefile
CFLAGS= -Wall -O2 -g
OBJS=lock.o
lock: $(OBJS)
gcc -o $@ $(OBJS)
clean:
rm -rf lock $(OBJS) file.lock
编译
# make
cc -Wall -O2 -g -c -o lock.o lock.c
gcc -o lock lock.o
验证
窗口1
# ./lock
file has been locked by 23791. press any key to unlock
<-- 1) 按任意键,释放锁
file has been unlocked by 23791.
窗口2
# ./lock
waiting for lock
<-- 等待锁释放,1)按下任意键后继续
file has been locked by 23792. press any key to unlock
<-- 2) 按任意键,释放锁
file has been unlocked by 23792.
网友评论