文件锁
fcntl解决文件共享的问题,而select处理I/O复用的情况。
flock 用于对文件施加建议性锁, 而 fcntl 不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl 还能对文件的某一记录进行 上锁,也就是记录锁。
记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,它能够使多个进程都能在 文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个进程在文件的 某个部分上建立写入锁。当然,在文件的同一部分不能同时建立读取锁和写入锁。
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
函数原型 int fcnt1(int fd,int cmd,struct flock *lock)
struct flock{
short l_type; //锁的类型F_RDLCK读取锁(共享锁),F_WRLCK写入锁(排斥锁),F_UNLCK解锁
off_t l_start; //相对位移量(字节)
short l_whence; //相对位移量的起点
off_t l_len; //加锁区的长度
pid_t l_pid;
}
#include<stdio.h> #include<sys/file.h> // #include<sys/stat.h> //文件状态 #include<stdlib.h> #include<unistd.h> #include<sys/types.h> int lock_set(int fd,int type) { struct flock lock; lock.l_start=0; lock.l_whence=SEEK_SET; lock.l_len=10; while(1){ lock.l_type=type; /*根据不同的type给文件上锁或解锁*/ if((fcntl(fd,F_SETLK,&lock))==0){ //F_SETLK设置lock描述的锁 if(lock.l_type==F_RDLCK) //读锁(共享锁) printf("read lock set by &d\n",getpid()); else if(lock.l_type==F_WRLCK) //写锁(排斥锁) printf("write lock set by %d\n",getpid()); else if(lock.l_type==F_UNLCK) //解锁 printf("release lock by %d\n",getpid()); return; //如果上锁成功,则函数返回 } fcntl(fd,F_GETLK,&lock); //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 alrady set by %d\n",lock.l_pid); getchar(); } } } int main() { int fd; //打开文件 fd=open("test",O_RDWR|O_CREAT,0666); if(fd<0){ perror("open"); exit(1); } //给文件上写入锁 lock_set(fd,F_WRLCK); //用户按下一个键后解锁 getchar(); lock_set(fd,F_UNLCK); getchar(); close(fd); exit(0); }
在两个终端上同时运行这个程序试一下。
进程1对文件设置排斥锁后其他进程就不能再对文件设置排斥锁;但是多个进程可以对同一个文件设置共享锁。
本文来自博客园,作者:高性能golang,转载请注明原文链接:https://www.cnblogs.com/zhangchaoyang/articles/1941332.html