【C语言】【unix c】文件锁的使用

110 篇文章 1 订阅
四、文件锁的使用
    1、在进程PA操作文件的时候先加锁,加锁成功后然后访问文件。在加锁期间其他进程不能对文件进行改动
    2、访问结束后释放锁
        文件锁分为两种:读锁(共享锁)和写锁(互斥锁)
        文件对锁的实现分为两类:建议锁和强制锁
    3、如何对文件加锁:
        使用系统调用fcntl(2)对文件的加锁
               #include <unistd.h>
               #include <fcntl.h>
               int fcntl(int fd, int cmd, ... /* arg */ );
                功能:操作文件描述符
                参数:
                    fd:指定了要操控的文件描述
                    cmd:指定了操作文件描述符(这里的三个都需要第三个参数)
                        F_GETLK:用来测试是否可以加锁,如果可以,返回F_UNLCK。不可以加锁在字段l_pid中保存了一个pid。是hold着这把锁的进程的pid
                        F_SETLK:为文件描述符设置锁,如果有互斥锁,其他进程hold着互斥锁,立即返回-1,错误,errno被设置
                        F_SETLKW:和F_SETLK一样,但是如果想要加的锁和文件已有记录锁冲突,进程阻塞等待进程对记录锁的释放

                    ...:可变参数,参数的类型和个数取决于CMD
                        struct flock *
                        struct flock {
                                   ...
                                   short l_type;    /* Type of lock: F_RDLCK,F_WRLCK, F_UNLCK */  读取锁(共享锁),写入锁(排斥锁),解锁
                           相对位移量的起点short l_whence;  /* How to interpret l_start:EEK_SET, SEEK_CUR, SEEK_END */ 头,当前位置,文件尾部
                        相对位移量     off_t l_start;   /* Starting offset for lock */
                        加锁区域的长度 off_t l_len;     /* Number of bytes to lock */
                                   pid_t l_pid;     /* PID of process blocking our lock(F_GETLK only) */
                                   ...
                               };
                返回值:0代表成功
                    -1 错误 errno被设置


        举例:文件锁的使用
            有两个进程PA,PB,PA进程对文件加读锁,PB进程对同一文件也加读锁,是否成功?(PA.c,PB.c)
                #include <stdio.h>
                #include <p_file.h>

                int main(int argc, char *argv[]) {
                    int fd = open(argv[1], O_RDONLY);
                    struct flock lock;
                    if(fd == -1) {
                    perror("open");
                    return -1;
                    }
                    //对锁变量设置初值
                    lock.l_type = F_RDLCK;
                    lock.l_whence = SEEK_SET;
                    lock.l_start = 0;
                    lock.l_len = 0;
                    lock.l_pid = 0;
                    //对文件描述符加锁
                    int f = fcntl(fd, F_SETLK, &lock);
                    if(f == -1) {
                    perror("fcntl");
                    return -1;
                    }
                    getchar();
                    //close 将关闭掉文件描述符上的所有记录锁
                    close(fd);
                    return 0;
                }
                A为写锁,B为写锁
                A:
                tarena@ubuntu:~/day/day28$ A hello
                -
                B
                tarena@ubuntu:~/day/day28$ gcc PB.c -o B
                tarena@ubuntu:~/day/day28$ B hello 
                add lock success..

                A为写锁,B为读锁
                修改:int fd = open(argv[1], O_WRONLY);
                      lock.l_type = F_WRLCK
                A:
                tarena@ubuntu:~/day/day28$ A hello
                -
                B:
                tarena@ubuntu:~/day/day28$ B hello 
                -
                当进程A结束,B马上加锁成功

        举例:测试文件锁是否能添加。(PC.c PD.c)(程序PA运行中进行下面)
                PC.c:
                    #include <stdio.h>
                    #include <p_file.h>

                    int main(int argc, char *argv[]) {
                        struct flock lock;
                        int fd = open(argv[1], O_RDONLY);
                        if(fd == -1) {
                        perror("open");
                        return -1;
                        }
                        //对锁变量设置初值
                        lock.l_type = F_RDLCK;
                        lock.l_whence = SEEK_SET;
                        lock.l_start = 0;
                        lock.l_len = 0;
                        lock.l_pid = 0;

                        int f = fcntl(fd, F_GETLK, &lock);
                        if(f == -1) {
                        perror("fcntl");
                        return -1;
                        }
                        if(lock.l_type == F_UNLCK) {
                        printf("can add read lock...\n");
                        }
                        else {
                        printf("hold lock %d of process",lock.l_pid);
                        }
                        return 0;
                    }
                    tarena@ubuntu:~/day/day28$ C hello 
                    can add read lock...
                分析: 读锁可以添加
                PD.c
                    修改:
                    int fd = open(argv[1], O_WRONLY);
                    lock.l_type = F_WRLCK

                    tarena@ubuntu:~/day/day28$ D hello 
                    hold lock 4350 of process
                分析:写锁不能添加,返回占用的进程的PID
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘星燎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值