文件锁仅在不同进程间访问起作用。
通过锁同步多个进程对同一个文件的读写访问。
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<sys/types.h>
#include<stdlib.h>
#define LEN 1000
void menu(){
printf("------------------------\n");
printf("********菜单**********\n");
printf("********1.写 ******\n");
printf("********2.读 ******\n");
printf("********3.测试能否上锁\n");
printf("********4.上读锁 **\n");
printf("********5.上写锁 **\n");
printf("********6.解锁 **\n");
printf("********7.退出 **\n");
}
void plock(struct flock lock){
if(lock.l_type == F_UNLCK){
printf("能上锁\n");
}else{
printf("%d进程,",lock.l_pid);
switch(lock.l_whence){
case SEEK_SET:
printf("在距离文件头");
break;
case SEEK_CUR:
printf("在距离当前位置");
break;
case SEEK_END:
printf("在距离文件末尾位置");
break;
}
printf("偏移%ld,长度为%ld",lock.l_start,lock.l_len);
switch(lock.l_type ){
case F_RDLCK:
printf("为读锁\n");
break;
case F_WRLCK:
printf("为写锁\n");
break;
}
}
}
int wtest(int fd,off_t start,off_t len){
struct flock lock={};
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
lock.l_pid =-1;
if(fcntl(fd,F_GETLK,&lock) == -1){
return -1;
}
plock(lock);
return 0;
}
int rtest(int fd,off_t start,off_t len){
struct flock lock={};
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
lock.l_pid =-1;
if(fcntl(fd,F_GETLK,&lock) == -1){
return -1;
}
plock(lock);
return 0;
}
int w_lock(int fd,off_t start,off_t len){
struct flock lock = {};
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
lock.l_pid = -1;
printf("0.上阻塞的锁\n");
printf("1.上非阻塞的锁\n");
int wait = 0;
scanf("%d",&wait);
return fcntl(fd,wait?F_SETLK:F_SETLKW,&lock);
}
int r_lock(int fd,off_t start,off_t len){
struct flock lock = {};
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
lock.l_pid = -1;
printf("0.上阻塞的锁\n");
printf("1.上非阻塞的锁\n");
int wait = 0;
scanf("%d",&wait);
return fcntl(fd,wait?F_SETLK:F_SETLKW,&lock);
}
int un_lock(int fd,off_t start,off_t len){
struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = len;
lock.l_pid = -1;
return fcntl(fd,F_SETLK,&lock);
}
void test(const char *filename){
int fd = open(filename,O_CREAT|O_RDWR,0644);
if(fd == -1){
perror("open:");
return;
}
while(1){
menu();
int opt = 0;
printf("请输入选择:\n");
scanf("%d",&opt);
switch(opt){
case 1:{
char str[LEN]={};
printf("请输入要写入文件的数据:\n");
scanf("%s",str);
lseek(fd,0,SEEK_END);
int res = write(fd,str,strlen(str));
if(res == -1){
perror("write:");
return;
}
}
break;
case 2:{
char mid[LEN];
lseek(fd,0,SEEK_SET);
while(read(fd,mid,LEN)>0){
printf("%s",mid);
}
printf("\n");
}
break;
case 3:{
printf(">>>>>\n");
printf("*****1.能否上读锁*****\n");
printf("*****2.能否上写锁*****\n");
printf("请输入选择:\n");
int opt = 0;
scanf("%d",&opt);
printf("请输入上锁的偏移距离:\n");
off_t start = 0;
scanf("%ld",&start);
printf("请输入上锁的长度:\n");
off_t len = 0;
scanf("%ld",&len);
if(opt == 1){
rtest(fd,start,len);
}else{
wtest(fd,start,len);
}
}
break;
case 4:{
printf("请输入上锁的偏移距离:\n");
off_t start = 0;
scanf("%ld",&start);
printf("请输入上锁的长度:\n");
off_t len = 0;
scanf("%ld",&len);
if(r_lock(fd,start,len)==-1){
printf("上锁失败\n");
}else{
printf("上锁成功\n");
}
}
break;
case 5:{
printf("请输入上锁的偏移距离:\n");
off_t start = 0;
scanf("%ld",&start);
printf("q请输入上锁的长度:\n");
off_t len = 0;
scanf("%ld",&len);
if(w_lock(fd,start,len)==-1){
printf("上锁失败\n");
}else{
printf("上锁成功\n");
}
}
break;
case 6:{
printf("请输入解锁的偏移距离:\n");
off_t start = 0;
scanf("%ld",&start);
printf("q请输入解锁的长度:\n");
off_t len = 0;
scanf("%ld",&len);
if(un_lock(fd,start,len)==-1){
printf("解锁失败\n");
}else{
printf("解锁成功\n");
}
}
break;
case 7:
exit(0);
}
}
close(fd);
}
int main(int argc,char *argv[]){
if(argc<2){
printf("%d is not enough!\n",argc);
return -1;
}
test(argv[1]);
return 0;
}