歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網

高級IO

日期:2017/3/3 12:53:13   编辑:Linux技術

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

Copyright © Linux教程網 All Rights Reserved