文件锁

  如果对一个文件的同一个区域同时读和写,则会发生冲突,导致读和写发生错误,所以要使用文件锁对其进行锁定。

  当我们对一个文件写入时,其他进程对其不能进行操作,而对其读时,其他进程不可以写但是可以读。即写独占,读共享。

  因此,读锁相当于一个共享锁,对于一个文件的一个区域可以同时加多把锁。而对于一个写锁,对于某个文件只能在一个区域加入一把锁。

  使用函数: int fcntl(int fd, F_SETLK/F_SETLKW, struct flock *lock);

  fd:文件描述符。

  F_SETLKW/F_SETLK:是否需要阻塞锁。

  flock为一个结构体:

    struct flock{

        short int l_type; //锁的类型,包括F_RDLCK, F_WRLCK, F_UNLCK

        short int l_whence; //锁的偏移地点,包括:SEEK_SET, SEEK_CUR, SEEK_END

        off_t l_start;   //锁的偏移

        off_t l_len     //锁区的长度

        pid_t l_pid    //加锁进程的pid, -1代表自动设置

    }

  如果我们对于文件头10个字节开始,加一个长度为20字节的阻塞模式的读锁,应该为:

  

struct flock lock;
lock.l_type   = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start    = 10;
lock.l_len      = 20;
lock.l_pid      = -1;
fcntl(fd, F_SETLKW, &lock);

  实例代码如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
// 加读锁
int rlock(int fd, off_t start, off_t len,
    int wait) {
    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;
    return fcntl(fd, wait ? F_SETLKW : F_SETLK,
        &lock);
}
// 加写锁
int wlock(int fd, off_t start, off_t len,
    int wait) {
    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;
    return fcntl(fd, wait ? F_SETLKW : F_SETLK,
        &lock);
}
// 解除锁
int ulock(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);
}
int main(void) {
    printf("进程标识(PID):%d\n", getpid());
    int fd = open("shared.txt", O_RDWR |
        O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        return -1;
    }
    const char* text = "ABCDEFGHIJKLMNOPQRST";
    if (write(fd, text, strlen(text) * sizeof(
        text[0])) == -1) {
        perror("write");
        return 0;
    }
    printf("对EFGH加读锁");
    if (rlock(fd, 4, 4, 0) == -1) {
        printf("失败:%m\n");
        return -1;
    }
    printf("成功!\n");
    printf("对MNOP加写锁");
    if (wlock(fd, 12, 4, 0) == -1) {
        printf("失败:%m\n");
        return -1;
    }
    printf("成功!\n");
    printf("按<回车>,解锁MN...");
    getchar();
    ulock(fd, 12, 2);
    printf("按<回车>,解锁EFGH...");
    getchar();
    ulock(fd, 4, 4);
    close(fd);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值