首先学习文章:http://www.cnblogs.com/nufangrensheng/p/3554168.html 和http://blog.youkuaiyun.com/anonymalias/article/details/9197641
然后写代码验证
#include <stdio.h>
#include <fcntl.h>
/*
测试记录锁相关的操作
*/
int main(int argc , char *argv[]){
int fd ,retval ;
struct flock flck;
if( argc < 2 )
oops( "argc:" );
//open file
fd = open( argv[1] , O_RDWR | O_CREAT | O_TRUNC );
// fd = open( argv[1] , O_RDONLY );
lock_init( &flck , F_WRLCK , SEEK_SET , 0 , 0 );
printf( "before test," );
pr_type( flck.l_type);
/*
从下面结果可以看到,不管文件属性是什么,当没有加锁时
F_GETLK 都会返回F_UNLCK
*/
printf( "after test read type,");
test_lock( fd , F_WRLCK );
printf( "after test write type ,");
test_lock( fd , F_RDLCK );
/*
从下面的结果可以看到,当给文件加锁时候, 文件必须要
有相应的属性 F_RDLCK对应O_RDONLY和O_RDWR ,同样。。。
*/
//now set a lock
if( 0 == read_lock( fd ) )
oops( " read lock. ");
printf( "after set read type ,");
retval = test_lock( fd , F_RDLCK );
printf( "set lock return :%d.\n" , retval);
if( 0 == write_lock( fd ) )
oops( "write lock. ");
printf( "after set write type ,");
retval = test_lock( fd , F_WRLCK );
printf( "set lock return :%d.\n" , retval);
printf( "after set read type ,");
retval = test_lock( fd , F_RDLCK );
printf( "set lock return :%d.\n" , retval);
return 0;
}
#include <fcntl.h>
#include <stdio.h>
//#include <boolean.h>
#include "oops.h"
/*
fcntl 记录锁函数
*/
//enum bool = {false ,true};
void pr_type( const short l_type){
switch(l_type){
case F_RDLCK:
printf( "flock type is F_RDLCK.\n" );
break;
case F_WRLCK:
printf( "flock type is F_WRLCK.\n" );
break;
case F_UNLCK:
printf( "flock type is F_UNLCK.\n" );
break;
default:
printf( "flock type is unkown.\n" );
break;
}
}
int fcntl_fl_test( const int fd , const int type ){
int val ;
if( ( val = fcntl( fd , F_GETFL ) ) < 0 )
oops( "getfl" );
if( ( val & O_ACCMODE) == type )
return 1;
else
return 0;
}
void lock_init( struct flock *ptr , short type , short
whence , off_t start ,off_t len ){
if( ptr == NULL )
return ;
ptr->l_type = type;
ptr->l_whence = whence;
ptr->l_start = start;
ptr->l_len = len;
}
int read_lock( const int fd ){
struct flock flck;
//check if file has read access
// if( !fcntl_fl_test( fd , F_RDLCK ) ){
// printf( " file has not read access.\n");
// return 0;
// }
//init and set flock
lock_init( &flck , F_RDLCK , SEEK_SET , 0 , 0);
if( fcntl( fd , F_SETLK , &flck ) == -1 ){
printf( " fcntl return error.\n" );
return 0;
}
else
return 1;
}
int write_lock( const int fd ){
struct flock flck;
//check if file has read access
// if( !fcntl_fl_test( fd , F_WRLCK ) ){
// printf( " file has not write access.\n");
// return 0;
// }
//init and set flock
lock_init( &flck , F_WRLCK , SEEK_SET , 0 , 0);
if( fcntl( fd , F_SETLK , &flck ) == -1 ){
printf( " fcntl return error.\n" );
return 0;
}
else
return 1;
}
pid_t test_lock(const int fd ,const int type){
struct flock flck;
//init flock
lock_init( &flck , type , SEEK_SET , 0 , 0);
//test if we can create a lock
if( fcntl( fd , F_GETLK , &flck ) == -1 )
return -1;
pr_type( flck.l_type);
if( F_UNLCK == flck.l_type )
return 0;
else
return flck.l_pid;
}
然后看结果:
上面说明的兼容性规则适用于不同进程提出的锁请求,并不适用于单个进程提出的多个锁请求。如果一个进程对一个文件区间已经有了一把锁,后来该进程又企图在同一文件区间再加一把锁,那么新锁将替换老锁。例如,若一进程在某文件的16-32字节区间有一把写锁,然后又试图在16-32字节区间加一把读锁,那么该请求将成功执行(假定其他进程此时并不试图向该文件的同一区间加锁),原来的写锁被替换为读锁。