文件锁是一种文件读写机制,在任何特定的时间只允许一个进程访问一个文件。利用这种机制能够使读写单个文件的过程变得更安全。这里我们使用flock()函数。
flock函数说明
flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。
表头文件 #include<sys/file.h>
定义函数 int flock(int fd,int operation);
参数 operation有下列四种情况:
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。
返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。
用法:flock只要在打开文件后,需要对文件读写之前flock一下就可以了,用完之后再flock一下,前面加锁,后面解锁。
进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误。
flock锁的释放非常具有特色,即可调用LOCK_UN参数来释放文件锁,也可以通过关闭fd的方式来释放文件锁(flock的第一个参数是fd),意味着flock会随着进程的关闭而被自动释放掉
示例代码
test1.c:
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f = fopen("temp", "w+");
if(!f)
{
printf("error file\n");
return 0;
}
if(0 == flock(fileno(f), LOCK_EX))
{
printf("lock...\n");
getchar();
fclose(f);
flock(fileno(f), LOCK_UN);
}
else
{
printf("lock failed\n");
}
return 0;
}
test2.c
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
int main()
{
FILE *fp;
char text[]="this is a test!";
if((fp = fopen("temp", "w+")) == 0)
printf("can't open file!\n");
else
{
printf("open file success!\n");
int i = flock(fileno(fp), LOCK_SH | LOCK_NB); // 加锁以判断文件是否已经被加锁了
printf("%d\n", i);
flock(fileno(fp), LOCK_UN);
fwrite(text, strlen(text), 1, fp);
}
fclose(fp);
return 0;
}
测试如下:
在终端1中,运行test1
在终端2中,运行test2
i == 0 表示文件加锁成功, i == -1 表示文件已被加锁,不建议执行后续操作,这里为-1表示文件已经被加锁。
文件锁是一种文件读写机制,在任何特定的时间只允许一个进程访问一个文件。利用这种机制能够使读写单个文件的过程变得更安全。这里我们使用flock()函数。
flock函数说明
flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。
表头文件 #include<sys/file.h>
定义函数 int flock(int fd,int operation);
参数 operation有下列四种情况:
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。
返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。
用法:flock只要在打开文件后,需要对文件读写之前flock一下就可以了,用完之后再flock一下,前面加锁,后面解锁。
进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误。
flock锁的释放非常具有特色,即可调用LOCK_UN参数来释放文件锁,也可以通过关闭fd的方式来释放文件锁(flock的第一个参数是fd),意味着flock会随着进程的关闭而被自动释放掉
示例代码
test1.c:
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f = fopen("temp", "w+");
if(!f)
{
printf("error file\n");
return 0;
}
if(0 == flock(fileno(f), LOCK_EX))
{
printf("lock...\n");
getchar();
fclose(f);
flock(fileno(f), LOCK_UN);
}
else
{
printf("lock failed\n");
}
return 0;
}
test2.c
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
int main()
{
FILE *fp;
char text[]="this is a test!";
if((fp = fopen("temp", "w+")) == 0)
printf("can't open file!\n");
else
{
printf("open file success!\n");
int i = flock(fileno(fp), LOCK_SH | LOCK_NB); // 加锁以判断文件是否已经被加锁了
printf("%d\n", i);
flock(fileno(fp), LOCK_UN);
fwrite(text, strlen(text), 1, fp);
}
fclose(fp);
return 0;
}
测试如下:
在终端1中,运行test1
在终端2中,运行test2
i == 0 表示文件加锁成功, i == -1 表示文件已被加锁,不建议执行后续操作,这里为-1表示文件已经被加锁。