红联Linux门户
Linux帮助

linux flock的碎碎念

发布时间:2016-03-07 10:46:02来源:linux网站作者:NearXDU

接触LinuxC编程没几天,发现一个小Bug。在用Fflock函数给文件加上全局锁后,仍然可以调用文件API函数对该加锁的文件进行操作,例如:写操作。

后来上网查看得知。所谓flock提供加锁,是建议性锁,也就是说,使用flock之后,并不提供锁检查(这一点实在程序员写代码的时候体现)。实际上,那个所谓的程序员写的代码也就是在对受锁保护的文件进行操作之前对该文件“加锁”,根据返回值(若返回值不为0,则说明文件已经被其他进程加锁)来判断。


关于flock的测试代码如下:

先是在第一个终端下下通过给输入数字文件加锁:

//lock.c 
// 
// 
#include "file.h" 
main() 

char path[FILELENGTH]=PATH; 
char *filename="writetest.txt"; 
strcat(path,filename); 
//定义文件的路径和文件名 
///////////////////////////////////////////////// 

int fd; 
int i; 
extern int errno; 
 
fd=open(path,O_WRONLY|O_CREAT);//打开文件 
if(fd!=-1) 

printf("Open File: %s.\n",path); 
printf("Please input a number to lock the file.\n"); 
scanf("%d",&i); 
if(flock(fd,LOCK_EX)==0)//锁定文件 

printf("The File was Locked.\n");//提示信息 

else 

printf("The file was not locked.\n");//文件锁定失败 

printf("Please input a number to unlock the file.\n"); 
scanf("%d",&i); 
if(flock(fd,LOCK_UN)==0) 

printf("The File was Unlocked.\n"); 

else 

printf("The file was not unlocked.\n"); 

close(fd); 

else 

printf("Cannot open file %s.\n",path); 
printf("ERR:%s.\n",strerror(errno)); 


完成加锁后,第一个进程会在等待解锁的时候挂起,此时开启第二个终端运行locktest,代码如下(注意LOCK_NB的注释):

//locktest.c 
// 
// 
#include "file.h" 
main() 

char *filename = "writetest.txt"; 
char path[FILELENGTH]=PATH; 
strcat(path,filename); 
char s[]="ZhangXiao Is Loving Playing Dota2"; 
//文件路径与文件名 
///////////////////////////////////////// 
int fd; 
int i; 
extern int errno; 
fd=open(path,O_WRONLY|O_CREAT);//写方式打开,没有则创建 
if(fd!=-1) 

printf("Open File %s.\n",path); 
if(flock(fd,LOCK_EX|LOCK_NB)==0)//不加LOCK_NB,当文件被加锁后,进程将被阻塞直到解锁 
//可以测试去掉LOCK_NB,进程挂起,等另一个进程解锁,这边立刻运行。 

printf("The File was Locked.\n"); 

if(-1!=write(fd,s,sizeof(s))) 

printf("Write %s to the file %s\n",s,path); 

else 

printf("Cannot write the file %s\n",path); 
printf("ERR:%s\n",strerror(errno)); 


else 

printf("The file was locked by other process.Can't Write.\n"); 

close(fd); 

else 

printf("Cannot open file %s\n",path); 
printf("ERR:%s\n",strerror(errno)); 

}


本文永久更新地址:http://www.linuxdiyf.com/linux/18682.html