表头文件 #include
定义函数 int flock(int fd,int operation);
函数说明 flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。
在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock。
参数 operation有下列四种情况:
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。
返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。
int checkexit(char* pfile){ if (pfile == NULL) return -1; int lockfd = open(pfile,O_RDWR); if (lockfd == -1) return -2; int iret = flock(lockfd,LOCK_EX|LOCK_NB) if (iret == -1) return -3; return 0; }
下面为两个进程的实例:
file1.c
#include#include #include #include int main(void) { int fp = open("file_lock.test", O_WRONLY); int i = 20; if (fp == -1) //打开文件 { printf("file1 open error!\n"); } else{ printf("file1 open success!\n"); } if (flock(fp, LOCK_EX) != 0) //给该文件加锁 { printf("file1 lock by others\n"); } else{ printf("file1 no user by others\n"); } while (1) //进入循环,加锁时间为20秒,打印倒计时 { printf("%d\n", i--); sleep(1); if (i == 0) break; } close(fp); //20秒后退出,关闭文件 flock(fp, LOCK_UN); //文件解锁 return 0; }
file2.c
#include#include #include #include int main(void) { int fp = open("file_lock.test", O_WRONLY); int i = 0; if (fp == -1) //打开文件 { printf("file2 open error!\n"); }else{ printf("file2 open success!\n"); } if (flock(fp, LOCK_EX) != 0) //给该文件加锁 { printf("file2 lock by others\n"); } else{ printf("file2 no user by others\n"); } while(1) //进入循环 { printf("%d\n", i++); sleep(1); } close(fp); //关闭文件 flock(fp, LOCK_UN); //释放文件锁 return 0; }
1、4个文件,a进程文件a1,a2,b进程b1,b2
2、a进程加锁文件a1,b进程加锁文件b1
3、a进程创建a2文件,然后轮询查看b2文件是否存在(这里可以轮询,因为时间很短),不存在代表b进程还没创建,b进程同理
4、a进程轮询到b2文件存在了,代表b进程已经创建并可能在对b1文件加锁,此时删除文件b2,代表a进程已经加锁完毕,允许b进程读取a进程的锁,b进程同理
5、a进程监听文件a2,如果a2被删除,代表b进程进行到了步骤4已经对b1加锁完成,可以开始读取b1文件的锁(不能直接监听a2文件删除,也就是不能跳过34步,这也是最难想的一部分,如果那样可能此时b进程还没创建,和b进程创建完成并加锁完成的状态是一样的,就会让进程a误以为进程b加锁完成),b进程同理
a.c
#include#include #include #include #include <string.h> #include #define a1 "a1" #define a2 "a2" #define b1 "b1" #define b2 "b2" void observer_file_exist(char* file_path){ int lockFD = access(file_path, F_OK); while (lockFD == -1){ lockFD = access(file_path, F_OK); printf("wait %s create!\n", file_path); sleep(1); } printf("%s create finish!\n", file_path); } void observer_file_delete(char* file_path){ int lockFD = access(file_path, F_OK); while (lockFD != -1){ lockFD = access(file_path, F_OK); printf("wait %s to be delete!\n", file_path); sleep(1); } printf("%s create finish!\n", file_path); } void remove_path_file(char* file_path){ int lockFD = access(file_path,F_OK); if(lockFD!=-1){ printf("%s exsit remove ... ing!\n",file_path); int result=remove(file_path); printf("%s exsit remove finish!\n",file_path); }else{ printf("%s not exsit!\n",file_path); } } int main(void) { int fd1 = open(a1, O_WRONLY | O_CREAT,0777);; if (fd1 == -1) //打开文件 { printf("%s has been created and completed !\n", a1); } else{ printf("%s crate success!\n", a1); } if (flock(fd1, LOCK_EX) != 0) //给该文件加锁 { printf("no user by others, %s lock success\n",a1); }else{ printf("lock by others ,%s lock fail \n",a1); } int fd2 = open(a2, O_WRONLY | O_CREAT,0777);; if (fd2 == -1) //打开文件 { printf("%s has been created and completed !\n", a2); } else{ printf("%s crate success!\n", a2); } close(fd2); observer_file_exist(b2); remove_path_file(b2); observer_file_delete(a2); printf("b process crate success!\n"); printf("wait %s release lock.\n",b1); int fdb1 = open(b1, O_WRONLY); if (flock(fdb1, LOCK_EX) == 0){ printf("%s the file was unlocked \n",b1); }else{ printf("%s the file was not unlocked. \n",b1); } //close(fd1); return 0; }
b.c
#include#include #include #include #include <string.h> #include #define a1 "a1" #define a2 "a2" #define b1 "b1" #define b2 "b2" void observer_file_exist(char* file_path){ int lockFD = access(file_path,F_OK); while(lockFD == -1){ lockFD = access(file_path,F_OK); printf("wait %s create!\n",file_path); sleep(1); } printf("%s create finish!\n",file_path); } void observer_file_delete(char* file_path){ int lockFD = access(file_path,F_OK); while(lockFD != -1){ lockFD = access(file_path,F_OK); printf("wait %s to be delete!\n",file_path); sleep(1); } printf("%s create finish!\n",file_path); } void remove_path_file(char* file_path){ int lockFD = access(file_path,F_OK); if(lockFD!=-1){ printf("%s exsit remove ... ing!\n",file_path); int result=remove(file_path); printf("%s exsit remove finish!\n",file_path); }else{ printf("%s not exsit!\n",file_path); } } int main(void) { int fd1 = open(b1, O_WRONLY|O_CREAT,0777);; if (fd1 == -1) //打开文件 { printf("%s has been created and completed !\n",b1); }else{ printf("%s crate success!\n",b1); } if (flock(fd1, LOCK_EX) == 0) //给该文件加锁 { printf("no user by others, %s lock success\n",b1); }else{ printf("lock by others ,%s lock fail \n",b1); } int fd2 = open(b2, O_WRONLY|O_CREAT,0777);; if (fd2 == -1) //打开文件 { printf("%s has been created and completed !\n",b2); }else{ printf("%s crate success!\n",b2); } close(fd2); observer_file_exist(a2); remove_path_file(a2); observer_file_delete(b2); printf("a process crate success!\n"); printf("wait %s release lock.\n",a1); int fda1 = open(a1, O_WRONLY); if(flock(fda1, LOCK_EX)==0){ printf("%s the file was unlocked.\n",a1); } else{ printf("%s the file was not unlocked.\n",a1); } //close(fd1); return 0; }