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