F_GETLK:进程可以通过它来获取通过 fd 打开的那个文件的加锁信息。执行该操作时,lock
指向的结构中就保存了希望对文件加的锁(或者说要查询的锁)。如果确实存在这样一把锁,它阻止 lock 指向的 flock
结构所给出的锁描述符,则把现存的锁的信息写到 lock 指向的 flock 结构中,并将该锁拥有者的 PID 写入 l_pid
字段中,然后返回;否则,就将 lock 指向的 flock 结构中的 l_type 设置为 F_UNLCK,并保持 flock
结构中其他信息不变返回,而不会对该文件真正加锁。
F_SETLK:进程用它来对文件的某个区域进行加锁(l_type的值为 F_RDLCK 或 F_WRLCK)或者删除锁(l_type 的值为F_UNLCK),如果有其他锁阻止该锁被建立,那么 fcntl() 就出错返回
F_SETLKW:与 F_SETLK 类似,唯一不同的是,如果有其他锁阻止该锁被建立,则调用进程进入睡眠状态,等待该锁释放。一旦这个调用开始了等待,就只有在能够进行加锁或者收到信号时才会返回
需要注意的是,F_GETLK 用于测试是否可以加锁,在 F_GETLK 测试可以加锁之后,F_SETLK 和 F_SETLKW
就会企图建立一把锁,但是这两者之间并不是一个原子操作,也就是说,在 F_SETLK 或者 F_SETLKW
还没有成功加锁之前,另外一个进程就有可能已经插进来加上了一把锁。而且,F_SETLKW
有可能导致程序长时间睡眠。还有,程序对某个文件拥有的各种锁会在相应的文件描述符被关闭时自动清除,程序运行结束后,其所加的各种锁也会自动清除。
#include
#include
#include
#include
#include
void print_lock(struct flock lock);
int main(int argc,char ** argv)
{
struct flock lock;
struct flock lock2;
pid_t pid;
int fd,ret;
//给文件挂上写锁
fd = open("bar",O_RDWR);
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_len = 0;
lock.l_whence = SEEK_SET;
fcntl(fd,F_SETLK,&lock);
print_lock(lock);
//在其他进程对文件进行写锁测试
pid=fork();
if(pid==0)
{
printf("child process :\n");
lock2.l_type=F_RDLCK;
lock2.l_start=0;
lock2.l_len=0;
lock2.l_whence=SEEK_SET;
fcntl(fd,F_GETLK,&lock2);
print_lock(lock2);
}
close(fd);
return 0;
}
void print_lock(struct flock lock)
{
printf(" -----------------------------\n");
if (lock.l_type == F_RDLCK) {
printf("\tl_type: F_RDLCK\n");
}
else if (lock.l_type == F_WRLCK) {
printf("\tl_type: F_WRLCK\n");
}
else if (lock.l_type == F_UNLCK) {
printf("\tl_type: F_UNLCK\n");
}
printf("\tl_start: %d\n", (int)lock.l_start);
if (lock.l_whence == SEEK_SET) {
printf("\tl_whence: SEEK_SET\n");
}
else if (lock.l_whence == SEEK_CUR) {
printf("\tl_whence: SEEK_CUR\n");
}
else if (lock.l_whence == SEEK_END) {
printf("\tl_whence: SEEK_END\n");
}
printf("\tl_len: %d\n", (int)lock.l_len);
printf(" -----------------------------\n");
}
阅读(878) | 评论(0) | 转发(0) |