高级IO-fcntl记录锁

首先学习文章: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字节区间加一把读锁,那么该请求将成功执行(假定其他进程此时并不试图向该文件的同一区间加锁),原来的写锁被替换为读锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值