您的位置:首页 > 运维架构

fcntl函数配合getopt函数实现对任意文件的上锁和解锁操作程序

2011-07-21 17:01 429 查看
  本程序通过调用fcntl函数和getopt函数来实现对文件进行上锁(读取锁或者写入锁)和解锁操作,程序分别参考了下《嵌入式Linux C编程入门(第2版)》(P270,不过书中给的例子代码有错误以及有点瑕疵,个人修改了部分代码),《嵌入式Linux 应用程序开发标准教程(第2版)》(P160).

  对于fcntl函数和getopt函数的使用方法请自行搜索:

  以下是源程序代码:

/*file_lock.c 实现对hello文件(自己设定)的上锁和解锁功能*/
#include<unistd.h>
#include<sys/file.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*function: lock_set
 *return 1 mean failed
 *return 0 mean success
 */
int lock_set(int fd,int type)
{
	struct flock old_lock,lock;
	lock.l_whence = SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 0;
	lock.l_type = type;
	lock.l_pid = -1;

	/*判断文件是否可以上锁*/
	fcntl(fd,F_GETLK,&lock);
	if(lock.l_type != F_UNLCK)
	{
		/*判断文件不能上锁的原因*/
		if(lock.l_type == F_RDLCK)	//该文件已有读取锁
		{
			printf("Read lock already set by %d\n",lock.l_pid);
		}
		else if(lock.l_type == F_WRLCK)	//该文件已有写入锁
		{
			printf("Write lock already set by %d\n",lock.l_pid);
		}
	}

	/*l_type 可能已经被F_GETLK修改过*/
	lock.l_type = type;

	/*根据不同的type值进行阻塞式上锁或解锁*/
	if((fcntl(fd,F_SETLKW,&lock)) > 0)
	{
		printf("Lock failed:type = %d\n",lock.l_type);
		return 1;
	}

	switch (lock.l_type)
	{
		case F_RDLCK:
	 		printf("Read lock set by %d\n",getpid());
			break;
		case F_WRLCK:
	 		printf("Write lock set by %d\n",getpid());
			break;
		case F_UNLCK:
	 		printf("Release lock by %d\n",getpid());
			return 1;
			break;
		default :
			break;
	}//end of switch
	return 0;

}

int main(int argc,char *argv[])
{
	int fd,nwrite,nread,len,c;
	char reply;
	char buff[100] = {'0'};
	char buff_r[100] = {'0'};
	/*打开文件*/
	fd = open("hello",O_RDWR | O_CREAT,0666);
	if(fd < 0)
	{
		perror("open error");
		exit(1);
	}
	/*用getopt()函数分析命令行参数,获取客户端选项*/
	while((c = getopt(argc,argv,"w:r")) != -1)
		switch(c)
		{
			/*设置写入锁*/
			case 'w':
				strcpy(buff,optarg); 
				lock_set(fd,F_WRLCK);
				len = strlen(buff);
				if((nwrite = write(fd,buff,len)) > 0)
				{
					printf("write success\n");
				}
				while(1)
				{
					printf("want to  unlock?(Y/N)\n");
					scanf("%c",&reply);
					/*给文件继续保持锁定(N)或解锁(Y)*/
					if((reply == 'Y') || (reply == 'y'))
					{
						lock_set(fd,F_UNLCK);
						break; 
					}
					else
					{
						sleep(2); 
						continue;
					}
				}
 				break;

			/*设置读取锁*/
			case 'r':
				lock_set(fd,F_RDLCK);
				lseek(fd,0,SEEK_SET);
				if((nread = read(fd,buff_r,100)) > 0)
				{
					printf("read:%s\n",buff_r);
				}
				while(1)
				{
					printf("want to  unlock?(Y/N)\n");
					scanf("%c",&reply);
					
					/*给文件继续保持锁定(N)或解锁(Y)*/
					if((reply == 'Y') || (reply == 'y'))
					{
						lock_set(fd,F_UNLCK);
						break; 
					}
					else
					{
						sleep(2);
						continue; 
					}
				}
				break;
			default:
				printf("prog [-w+content] [-r]\n");
				break; 
		}
	close(fd);
	exit(0);
}


  运行结果:打开两个终端,(1)实现设置写入锁功能,见下图:



  已经设置写入锁成功,再次写入,则不可以:



  (2)实现读取锁功能,见下图:



  再来一个读取锁,同样可以,见下图,说明其是共享锁:



  最后,再介绍下利用gdb调试带有命令行参数的程序,大致步骤是:

1.gdb filename (我这里是file_lock)

2.b main (设置main断点)

3.r (输入参数) 比如我要读的话,输入r -r,见下图:



注意看第二行后面的那行“file_lock -r”同理若是写的话,输入 r -w file_lock



接下来可以进行调试了。

 
原创文章,欢迎转载,转载请注明:blog.csdn.net/jjzhoujun2010

作者:Dream Fly
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐