• linux文件锁


    目录

    一、概念 

    二、给整个文件上锁

    三、给文件的某个区域上锁    


    一、概念 

        为了解决不同进程操作同一个公共资源时,产生冲突的问题,
        引入文件锁,当进程操作共享资源时,要求每一个进程都先获取文件锁,然后才能操作共享资源
        文件锁分为:
            共享锁:多个进程可以同时获取
            互斥锁:在同一时刻只能有一个进程获取
        
        当多个进程操作公共资源时,谁先拿到互斥锁谁就可以对资源进行操作,其他进程就必须要等待,
        释放了互斥锁后,才可以获取,这样就解决了冲突的问题。
        

    上锁有两种方式:

    二、给整个文件上锁


         #include
        int flock(int fd, int operation);
        //参数1 ------ 要上锁的文件描述符
        //参数2 ------ 锁的类型  LOCK_SH   LOCK_EX   LOCK_UN
        //返回值 ---- 成功:0,失败:-1
        
        例如: 

    1. int main(int argc,char **argv)                            
    2. {                                                          
    3.     int fd;                                                
    4.     char *str = "farishgt";                                
    5.     int i;                                                  
    6.                                                            
    7.     if((fd = open(argv[1],O_RDWR|O_CREAT,0666)) < 0){      
    8.         perror("open");                                    
    9.         exit(1);                                          
    10.     }                                                      
    11.                                                            
    12.     //给文件上互斥锁                                      
    13.     if(flock(fd,LOCK_EX) < 0){                              
    14.         perror("flock");                                    
    15.         exit(1);                                          
    16.     }                                                      
    17.                                                            
    18.     //操作公共资源                                        
    19.     for(i = 0; i < 20; i++){                              
    20.         write(fd,str,strlen(str));                          
    21.         printf("%s\n",str);                                   
    22.         sleep(1);                                        
    23.     }                                                      
    24.                                                            
    25.     //解锁                                                
    26.     if(flock(fd,LOCK_UN) < 0){                               
    27.         perror("flock");                                  
    28.         exit(1);                                          
    29.     }                                                      
    30.     close(fd);                                          
    31.     return 0;                                              
    32. }                                                        
    1. int main(int argc,char **argv)
    2. {
    3.     int fd;
    4.     char *str = "helloworld";
    5.     int i;
    6.     if((fd = open(argv[1],O_RDWR|O_CREAT,0666)) < 0){
    7.         perror("open");
    8.         exit(1);
    9.     }
    10.     //给文件上互斥锁
    11.     if(flock(fd,LOCK_EX) < 0){
    12.         perror("flock");
    13.         exit(1);
    14.     }
    15.     //操作公共资源
    16.     for(i = 0; i < 20; i++){
    17.         write(fd,str,strlen(str));
    18.         printf("%s\n",str);
    19.         sleep(1);
    20.     }
    21.     //解锁
    22.     if(flock(fd,LOCK_UN) < 0){
    23.         perror("flock");
    24.         exit(1);
    25.     }
    26.     close(fd);
    27.     return 0;
    28. }


    三、给文件的某个区域上锁    

        #include
        include

        int fcntl(int fd, int cmd, ... /* arg */ );
        //参数1 ----- 文件描述符 
        //参数2 ----- 功能选项:
                        功能1:Duplicating a file descriptor(复制文件描述符)
                        功能2:File descriptor flags   (设置或获取文件描述符的标志位)
                        功能3:File status flags (设置或获取文件状态标志位:O_RDONLY, O_WRONLY, O_RDWR  O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC)
                        功能4: Advisory record locking(设置或获取文件锁) 
                                 struct flock {
                                       ...
                                       short l_type;    /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
                                       short l_whence;  /* How to interpret l_start:  SEEK_SET, SEEK_CUR, SEEK_END */
                                       off_t l_start;   /* Starting offset for lock  相对l_whence的偏移,也是锁的起始位置*/
                                       off_t l_len;     /* Number of bytes to lock 锁的区域大小*/
                                       pid_t l_pid;     /* PID of process blocking our lock    (set by F_GETLK and F_OFD_GETLK) 进程ID*/
                                       ...
                                   };
                        功能5: Managing signals(管理进程中收到的信号)
        //变参 ------ 根据参数2的不同,而传递不同类型的变参
        //返回值 ----- 成功:0,失败:-1
        
        例如: 

    1. int main(int argc,char **argv)                          
    2. {                                                        
    3.     int fd;                                              
    4.     char *str = "老王正在上厕所";                          
    5.     int i;                                                
    6.                                                      
    7.     if((fd = open(argv[1],O_RDWR|O_CREAT,0666)) < 0){      
    8.         perror("open");                                    
    9.         exit(1);                                              
    10.     }                                                    
    11.                                                          
    12.     printf("等待厕所的门被打开\n");                      
    13.     //给文件的某个区域上锁                            
    14.     struct flock fl = {F_WRLCK, SEEK_SET,100,1024};        
    15.     if(fcntl(fd,F_SETLKW,&fl) < 0){                      
    16.         perror("flock");                                
    17.         exit(1);                                                
    18.     }                                                      
    19.                                                            
    20.     //操作公共资源                                        
    21.     for(i = 0; i < 20; i++){                                
    22.         write(fd,str,strlen(str));                        
    23.         printf("%s\n",str);                                      
    24.         sleep(1);                                        
    25.     }                                                      
    26.                                                          
    27.     //解锁                                                  
    28.     fl.l_type = F_UNLCK;                                  
    29.     if(fcntl(fd,F_SETLK,&fl) < 0){                        
    30.         perror("flock");                                       
    31.         exit(1);                                          
    32.     }                                                      
    33.     printf("老王上完厕所了!\n");                      
    34.     close(fd);                                            
    35.     return 0;                                              
    36. }                                                        
    1. #include <sys/file.h>
    2. int main(int argc,char **argv)
    3. {
    4.     int fd;
    5.     char *str = "小明正在上厕所";
    6.     int i;
    7.     if((fd = open(argv[1],O_RDWR|O_CREAT,0666)) < 0){
    8.         perror("open");
    9.         exit(1);
    10.     }
    11.     printf("等待厕所门打开\n");
    12.     //给文件的某个区域上锁
    13.     struct flock fl = {F_WRLCK, SEEK_SET,100,1024};
    14.     if(fcntl(fd,F_SETLKW,&fl) < 0){
    15.         perror("flock");
    16.         exit(1);
    17.     }
    18.     //操作公共资源
    19.     for(i = 0; i < 20; i++){
    20.         printf("%s\n",str);
    21.         sleep(1);
    22.     }
    23.     //解锁
    24.     fl.l_type = F_UNLCK;
    25.     if(fcntl(fd,F_SETLK,&fl) < 0){
    26.         perror("flock");
    27.         exit(1);
    28.     }
    29.     printf("小明上完厕所了\n");
    30.     close(fd);
    31.     return 0;
    32. }

  • 相关阅读:
    DOM节点(节点查找、节点创建、节点克隆、节点删除)
    【LeetCode】【剑指offer】【旋转数组的最小数字】
    [git]上传代码到github
    没有想好标题
    【培训】MMEdu离线版的使用:实现石头剪刀布图像分类的生成模型
    分布式解决方案 Percolator--详解
    基于单片机的感应自动门系统
    win10蓝屏重启故障修复经验分享
    算法思想总结
    LeetCode[145]二叉树的后序遍历
  • 原文地址:https://blog.csdn.net/qq_54075859/article/details/126621849