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

2019-07-12 18:29发布

  本程序通过调用fcntl函数和getopt函数来实现对文件进行上锁(读取锁或者写入锁)和解锁操作,程序分别参考了下《嵌入式Linux C编程入门(第2版)》(P270,不过书中给的例子代码有错误以及有点瑕疵,个人修改了部分代码),《嵌入式Linux 应用程序开发标准教程(第2版)》(P160).   对于fcntl函数和getopt函数的使用方法请自行搜索:
  以下是源程序代码: /*file_lock.c 实现对hello文件(自己设定)的上锁和解锁功能*/ #include #include #include #include #include #include #include /*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 ",lock.l_pid); } else if(lock.l_type == F_WRLCK) //该文件已有写入锁 { printf("Write lock already set by %d ",lock.l_pid); } } /*l_type 可能已经被F_GETLK修改过*/ lock.l_type = type; /*根据不同的type值进行阻塞式上锁或解锁*/ if((fcntl(fd,F_SETLKW,&lock)) > 0) { printf("Lock failed:type = %d ",lock.l_type); return 1; } switch (lock.l_type) { case F_RDLCK: printf("Read lock set by %d ",getpid()); break; case F_WRLCK: printf("Write lock set by %d ",getpid()); break; case F_UNLCK: printf("Release lock by %d ",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 "); } while(1) { printf("want to unlock?(Y/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 ",buff_r); } while(1) { printf("want to unlock?(Y/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] "); 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