1. 進程 A 排他鎖住某文件之後,進程 B 可以修改該文件,但不能鎖住該文件。
2. 進程 A 排他鎖住某文件之後,進程 B 修改該文件之後,因爲文件 inode 沒有改變,所以依然不能鎖住該文件。
3. 進程 A 排他鎖住某文件之後,進程 B 可以刪除該文件,並創建同名文件,此時進程 B 可以鎖住該文件。
由於 vi, sed 等程序修改文件會改變文件 inode, 所以會導致被 A 進程鎖住的文件,再用 vi, sed 等修改後依然能被進程 B 鎖住。
下面的例子模擬了上述情景:
locking——一直鎖住文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#include <stdio.h>
#define FILE_CONTENTS "123"
int main()
{
int fd;
if (0 == access("lock.txt", F_OK))
{
printf("remove lock.txt!\n");
if (-1 == remove("lock.txt"))
{
printf("remove() failed.\n");
return -1;
}
}
fd = open("lock.txt", O_RDWR | O_CREAT | O_TRUNC | O_APPEND, S_IRUSR | S_IWUSR);
if (-1 == fd)
{
printf("open() failed.\n");
return -1;
}
if (-1 == write(fd, FILE_CONTENTS, sizeof(FILE_CONTENTS)))
{
printf("write() failed.\n");
return -1;
}
if (-1 == flock(fd, LOCK_EX))
{
printf("flock() failed.\n");
return -1;
}
sleep(60);
if (-1 == close(fd))
{
printf("close() failed.\n");
return -1;
}
return 0;
}
try_lock——嘗試鎖住文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#include <stdio.h>
int main()
{
int fd;
printf("try_lock============================\n");
fd = open("lock.txt", O_RDONLY);
if (-1 == fd)
{
printf("open() failed.\n");
return -1;
}
printf("try lock!\n");
if (-1 == flock(fd, LOCK_EX | LOCK_NB))
{
printf("flock() failed.\n");
return -1;
}
if (-1 == close(fd))
{
printf("close() failed.\n");
return -1;
}
return 0;
}
append——追加修改鎖住的文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define FILE_APPENDED_CONTENTS "123"
int main()
{
int fd;
printf("append============================\n");
fd = open("lock.txt", O_RDWR | O_APPEND);
if (-1 == fd)
{
printf("open() failed.\n");
return -1;
}
printf("append something to lock.txt!\n");
if (-1 == write(fd, FILE_APPENDED_CONTENTS, sizeof(FILE_APPENDED_CONTENTS)))
{
printf("write() failed.\n");
return -1;
}
if (-1 == close(fd))
{
printf("close() failed.\n");
return -1;
}
return 0;
}
rm_create——先刪除鎖住的文件,再創建相同文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define FILE_CONTENTS "123"
int main()
{
int fd;
printf("rm_create============================\n");
printf("remove lock.txt!\n");
if (-1 == remove("lock.txt"))
{
printf("remove() failed.\n");
return -1;
}
printf("create lock.txt!\n");
fd = open("lock.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if (-1 == fd)
{
printf("open() failed.\n");
return -1;
}
if (-1 == write(fd, FILE_CONTENTS, sizeof(FILE_CONTENTS)))
{
printf("write() failed.\n");
return -1;
}
if (-1 == close(fd))
{
printf("close() failed.\n");
return -1;
}
return 0;
}
運行順序
1. 先單獨運行 locking
2. 按如下順序運行其他程序
#!/bin/sh
./try_lock
echo "################# before append"
ls -i lock.txt
./append
echo "################# after append"
ls -i lock.txt
./try_lock
echo "################# before rm_create"
ls -i lock.txt
./rm_create
echo "################# after rm_create"
ls -i lock.txt
./try_lock
輸出如下:
> ./run.sh
try_lock============================
try lock!
flock() failed.
################# before append
2172298 lock.txt
append============================
append something to lock.txt!
################# after append
2172298 lock.txt
try_lock============================
try lock!
flock() failed.
################# before rm_create
2172298 lock.txt
rm_create============================
remove lock.txt!
create lock.txt!
################# after rm_create
2172299 lock.txt
try_lock============================
try lock!
修改文件之後,inode 沒有變化,flock 失敗;刪除再創建相同文件,inode 改變,flock 成功。