一、排他锁:事务T对文件A加上该锁后,则其他事务不能再对A加任何类型的锁,直到在事务的末尾将资源上的锁释放为止,获取排他锁的事务既能读数据,也能修改数据
共享锁:事务T对文件A加上该锁后,其他事务只能对A加共享锁,不能加排他锁,直到已释放所有共享锁,获共享锁的事务只能读数据,不能修改数据。。
二、Linux有两种方法可以实现文件锁:使用fcntl系统调用与使用lockf调用
三、fcntl函数原型:int fcntl(int fd, int cmd, struct flock *lock)
函数作用:对文件锁进行操作
头文件:<fcntl.h>
四、参数说明:
cmd:操作锁命令
F_SETLK:加锁或解锁,如果加锁失败。则fcntl立即返回,此时errno被设置为EAGIAN
F_SETLKW:这是F_SETLK的阻塞版本,如果加锁失败,则使调用进入休眠
F_GETLK:获取文件的加锁信息。注意:该命令并不会为文件加锁。成功时返回满足要求的文件个数,出错时返回-1.
//lock1.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
struct flock* file_lock(short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = 0;
ret.l_whence = whence;
ret.l_len = 0;
ret.l_pid = getpid();
return &ret;
}
int main()
{
int fd = open("1.txt", O_WRONLY|O_APPEND|O_CREAT);
int i;
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
for(i=0; i<10; ++i) {
char buf[1024] = {0};
/*sprintf把第三个参数带入第二个表达式参数,再把字符存到buf*/
sprintf(buf, "hello world %d/n/r", i);
int len = strlen(buf);
write(fd, buf, len);
sleep(1);
}
fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
close(fd);
}
//lock2.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
struct flock* file_lock(short type, short whence)
{
static struct flock ret;
ret.l_type = type ;
ret.l_start = 0;
ret.l_whence = whence;
ret.l_len = 0;
ret.l_pid = getpid();
return &ret;
}
int main()
{
int i;
int fd = open("1.txt", O_WRONLY|O_APPEND|O_CREAT);
fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
for(i=0; i<10; ++i) {
char buf[1024] = {0};
sprintf(buf, "china %d/n/r", i);
int len = strlen(buf);
write(fd, buf, len);
sleep(1);
}
fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
close(fd);
}