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
区域没有交叉,可以并存