本程序通过调用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); }
已经设置写入锁成功,再次写入,则不可以:
(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