linux文件锁实现

linux文件锁是默认的劝告锁。

以下证实两点:

1)读写锁分别的排他性。

2)当文件上锁区域交叉时的锁竞争关系。


FIleMutex.h:

class FileMutex {
public:
	FileMutex(const string& filename);
	virtual ~FileMutex();
	int lockR(int offset,int len);
	int lockW(int offset,int len);
	int lockRWait(int offset,int len,int millseconds);
	int lockWWait(int offset,int len,int millseconds);
	int unlock(int offset,int len);
private:
	int fd;
};

FileMutex.cpp

#include "FileMutex.h"

FileMutex::FileMutex(const string& filename) {
	fd = open(filename.c_str(),O_RDWR| O_CREAT, 0600);
	if(fd<0){
		perror("FileMutex init:");
	}

	cout << "fd:" << fd << endl;
	assert(fd);
}

FileMutex::~FileMutex() {
	if (fd > 0) {
		close(fd);
	}
}

int FileMutex::lockR(int offset, int len) {
	struct flock lock;
	lock.l_start = offset;
	lock.l_len = len;
	lock.l_type = F_RDLCK;
	lock.l_whence = SEEK_SET;
	int result=fcntl(fd, F_SETLK, &lock);
	if(result<0){
		perror("lockR:");
	}
	return result;
}

int FileMutex::lockW(int offset, int len) {
	struct flock lock;
	lock.l_start = offset;
	lock.l_len = len;
	lock.l_type = F_WRLCK;
	lock.l_whence = SEEK_SET;
	return fcntl(fd, F_SETLK, &lock);
}

int FileMutex::lockRWait(int offset, int len, int millseconds) {
	struct flock lock;
	lock.l_start = offset;
	lock.l_len = len;
	lock.l_type = F_RDLCK;
	lock.l_whence = SEEK_SET;
	return fcntl(fd, F_SETLKW, &lock);
}

int FileMutex::lockWWait(int offset, int len, int millseconds) {
	struct flock lock;
	lock.l_start = offset;
	lock.l_len = len;
	lock.l_type = F_WRLCK;
	lock.l_whence = SEEK_SET;
	return fcntl(fd, F_SETLKW, &lock);
}

int FileMutex::unlock(int offset, int len) {
	struct flock lock;
	lock.l_start = offset;
	lock.l_len = len;
	lock.l_type = F_UNLCK;
	lock.l_whence = SEEK_SET;
	return fcntl(fd, F_SETLK, &lock);
}

const option options[] = { { "file", required_argument, NULL, 'f' }, { "type", required_argument, NULL, 't' }, {
		"offset", required_argument, NULL, 'o' }, { "len", required_argument, NULL, 'l' }, { 0, 0, 0, 0 } };

int main(int argc, char **argv) {
	char cFileName[128];
	int type;
	int offset;
	int len;
	int ch;

	while ((ch = getopt_long(argc, argv, ":f:t:o:l:", options, NULL)) != -1) {
		switch (ch) {
		case 'f':
			strcpy(cFileName, optarg);
			break;
		case 't':
			type = atoi(optarg);
			break;
		case 'o':
			offset = atoi(optarg);
			break;
		case 'l':
			len = atoi(optarg);
			break;
		default:
			break;
		}
	}

	cout << "FileName:" << cFileName << " type:" << type << " offset:" << offset << " len:" << len << endl;
	FileMutex mutex(cFileName);
	int lockResult;
	if (type == 0) {
		lockResult = mutex.lockR(offset, len);
	}
	if (type == 1) {
		lockResult = mutex.lockW(offset, len);
	}
	cout << lockResult << endl;
	pause();
}

执行:

./mutex --file=lock1 --type=0 --offset=0--len=10  

./mutex --file=lock1 --type=0 --offset=10 --len=10 


两把读锁可以并存。


./mutex --file=lock1 --type=0 --offset=0 --len=10 

./mutex --file=lock1 --type=1 --offset=10 --len=10

读锁和写锁区域有交叉,不能并存,有一方将失败


./mutex --file=lock1 --type=0 --offset=0 --len=10 

./mutex --file=lock1 --type=1 --offset=11 --len=10  

区域没有交叉,可以并存

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值