首先學習文章:http://www.cnblogs.com/nufangrensheng/p/3554168.html 和http://blog.csdn.net/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字節區間加一把讀鎖,那麼該請求將成功執行(假定其他進程此時並不試圖向該文件的同一區間加鎖),原來的寫鎖被替換為讀鎖。