Linux 文件锁

Linux 文件锁

函数原型:int fcntl(int fd, int cmd, … /* arg */ );
参数说明

参数说明
fd文件描述符
cmd取值(仅说明文件锁相关):F_GETLK, F_SETLK, F_SETLKW 分别表示 获取锁、设置锁和同步设置锁
arg可变长参数

struck flock 数据结构 说明

struct flock {
	short l_type;	/*F_RDLCK, F_WRLCK, or F_UNLCK */
	off_t l_start;	/*offset in bytes, relative to l_whence */
	short l_whence;	/*SEEK_SET, SEEK_CUR, or SEEK_END */
	off_t l_len;	/*length, in bytes; 0 means lock to EOF */
	pid_t l_pid;	/*returned with F_GETLK */
};
成员说明
l_type加锁的类型,可为读锁<F_RDLCK>、写锁<F_WRLCK>、解锁<F_UNLCK>
l_start锁相对于l_whence的起始偏移量
l_whence取值:SEEK_SET、SEELK_CUR、SEEK_END 分别表示 开头、当前、结尾。说明:后两项若不是在文件头部 l_start 可取负数
l_len要锁定的字节数。若为正数,则表示从l_start开始,到l_start + l_len - 1为止;当取0时,则表示从l_start或l_whence开始,直到文件结尾。
l_pid获取对目标文件上锁的进场ID,仅在cmd取F_GETLK时生效
注意写锁为排他锁,读锁为共享锁

实例代码

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define FILE_NAME "./file/lock.txt"

/*********************************************************
 * 对fd进行加锁或解锁
*********************************************************/
int file_lock_set(int fd, int type) {
	if (fd < 0) {
		printf("file_lock_set() - fd(%d) < 0!\n", fd);
		return -1;
	}

	printf("pid = %d into!\n", getpid());

	// Query whether the file is locked.
	struct flock lock;
	memset(&lock, 0, sizeof(struct flock));

	fcntl(fd, F_GETLK, &lock);
	if (lock.l_type == F_RDLCK) {
		printf("fd(%d) has been read locked, locking process ID: %d!\n", fd, lock.l_pid);
	}
	else if (lock.l_type == F_WRLCK) {
		printf("fd(%d) has been write locked, locking process ID: %d!\n", fd, lock.l_pid);
	}

	lock.l_type = type;
	// F_SETLKW:若被加锁文件正在被其他进程加锁中,则阻塞等待。
	// F_SETLK:若被加锁文件正在被其他进程加锁中,则直接返回。
	if (fcntl(fd, F_SETLKW, &lock) < 0) {
		printf("set lock failed!\n");
		return -1;
	}

	switch (lock.l_type)
	{
	case F_RDLCK:
		printf("read lock is set by %d\n", getpid());
		break;
	case F_WRLCK:
		printf("write lock is set by %d\n", getpid());
		break;
	case F_UNLCK:
		printf("read lock is released by %d\n", getpid());
		break;
	default:
		break;
	}

	printf("pid = %d out!\n", getpid());
	return 0;
}

int main(void) {
	int fd = open(FILE_NAME, O_RDWR | O_CREAT, 0777);
	if (fd < 0) {
		printf("file(%s) open failed! reason: %s\n", FILE_NAME, strerror(errno));
		exit(-1);
	}

	// set lock.
	file_lock_set(fd, F_WRLCK);
	getchar();
	// unlock.
	file_lock_set(fd, F_UNLCK);
	getchar();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值