使用flock, open and close file实现多读单写锁
using flock, open and close file to implement many readers single writer lock
我有一个项目包含多个进程,可以读取或写入单个数据库。我希望使用系统调用 flock/open/close 实现由锁文件同步的单写入器/多读取器锁。
锁定失败后,任何重新尝试再次获取锁定,将由请求锁定的更高级别进行(与自旋锁定不同)。
不幸的是,在测试这个模型时,它在解锁之前没有锁定的情况下失败了。
也许你可以帮我找出我做错了什么:
// keep read and write file descriptors as global variables.
// assuming no more than 1 thread can access db on each process.
int write_descriptor=0;
int read_descriptor=0;
int lock_write() {
if((write_descriptor = open(LOCKFILE, O_RDWR|O_CREAT,0644))<0) {
return LOCK_FAIL;
}
if(flock(write_descriptor, LOCK_EX)<0) {
close(write_descriptor);
write_descriptor = 0;
return LOCK_FAIL;
}
return LOCK_SUCCESS;
}
int unlock_write() {
if(!write_descriptor) {
// sanity: try to unlock before lock.
return LOCK_FAIL;
}
if(flock(write_descriptor,LOCK_UN)<0) {
// doing nothing because even if unlock failed, we
// will close the fd anyway to release all locks.
}
close(write_descriptor);
write_descriptor = 0;
return LOCK_SUCCESS;
}
int lock_read() {
if((read_descriptor = open(LOCKFILE,O_RDONLY))<0) {
return LOCK_FAIL;
}
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
return LOCK_FAIL;
}
return LOCK_SUCCESS;
}
int unlock_read() {
if(!read_descriptor) {
// sanity : try to unlock before locking first.
return LOCK_FAIL;
}
if(flock(read_descriptor, LOCK_UN)<0) {
// doing nothing because even if unlock failed, we
// will close the fd anyway to release all locks.
}
close(read_descriptor);
read_descriptor = 0;
return LOCK_SUCCESS;
}
int read_db() {
if(lock_read() != LOCK_SUCCESS) {
return DB_FAIL;
}
// read from db
if(unlock_read() != LOCK_SUCCESS) {
// close fd also unlock - so we can fail here (can i assume that ?)
}
}
int write_db() {
if(lock_write() != LOCK_SUCCESS) {
return DB_FAIL;
}
//write to db.
if(unlock_write() != LOCK_SUCCESS) {
// close fd also unlock - so we can fail here (can i assume that ?)
}
}
在 lock_read
和 lock_write
中将此添加为第一行:
assert ((read_descriptor == 0) && (write_descriptor == 0));
在unlock_read
中添加:
assert (read_descriptor != 0);
并在 unlock_write
中添加:
assert (write_descriptor != 0);
并更改代码如下:
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
return LOCK_FAIL;
}
至:
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
read_descriptor = 0;
return LOCK_FAIL;
}
对编写代码执行相同操作,以便在关闭描述符时,相应的全局设置为零。 (你真的应该使用 -1 作为无效的文件描述符,因为零是合法的。)
制作调试版本并运行它。 assert
绊倒时,罪魁祸首就是你。
我有一个项目包含多个进程,可以读取或写入单个数据库。我希望使用系统调用 flock/open/close 实现由锁文件同步的单写入器/多读取器锁。
锁定失败后,任何重新尝试再次获取锁定,将由请求锁定的更高级别进行(与自旋锁定不同)。
不幸的是,在测试这个模型时,它在解锁之前没有锁定的情况下失败了。 也许你可以帮我找出我做错了什么:
// keep read and write file descriptors as global variables.
// assuming no more than 1 thread can access db on each process.
int write_descriptor=0;
int read_descriptor=0;
int lock_write() {
if((write_descriptor = open(LOCKFILE, O_RDWR|O_CREAT,0644))<0) {
return LOCK_FAIL;
}
if(flock(write_descriptor, LOCK_EX)<0) {
close(write_descriptor);
write_descriptor = 0;
return LOCK_FAIL;
}
return LOCK_SUCCESS;
}
int unlock_write() {
if(!write_descriptor) {
// sanity: try to unlock before lock.
return LOCK_FAIL;
}
if(flock(write_descriptor,LOCK_UN)<0) {
// doing nothing because even if unlock failed, we
// will close the fd anyway to release all locks.
}
close(write_descriptor);
write_descriptor = 0;
return LOCK_SUCCESS;
}
int lock_read() {
if((read_descriptor = open(LOCKFILE,O_RDONLY))<0) {
return LOCK_FAIL;
}
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
return LOCK_FAIL;
}
return LOCK_SUCCESS;
}
int unlock_read() {
if(!read_descriptor) {
// sanity : try to unlock before locking first.
return LOCK_FAIL;
}
if(flock(read_descriptor, LOCK_UN)<0) {
// doing nothing because even if unlock failed, we
// will close the fd anyway to release all locks.
}
close(read_descriptor);
read_descriptor = 0;
return LOCK_SUCCESS;
}
int read_db() {
if(lock_read() != LOCK_SUCCESS) {
return DB_FAIL;
}
// read from db
if(unlock_read() != LOCK_SUCCESS) {
// close fd also unlock - so we can fail here (can i assume that ?)
}
}
int write_db() {
if(lock_write() != LOCK_SUCCESS) {
return DB_FAIL;
}
//write to db.
if(unlock_write() != LOCK_SUCCESS) {
// close fd also unlock - so we can fail here (can i assume that ?)
}
}
在 lock_read
和 lock_write
中将此添加为第一行:
assert ((read_descriptor == 0) && (write_descriptor == 0));
在unlock_read
中添加:
assert (read_descriptor != 0);
并在 unlock_write
中添加:
assert (write_descriptor != 0);
并更改代码如下:
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
return LOCK_FAIL;
}
至:
if(flock(read_descriptor, LOCK_SH)<0) {
close(read_descriptor);
read_descriptor = 0;
return LOCK_FAIL;
}
对编写代码执行相同操作,以便在关闭描述符时,相应的全局设置为零。 (你真的应该使用 -1 作为无效的文件描述符,因为零是合法的。)
制作调试版本并运行它。 assert
绊倒时,罪魁祸首就是你。