浅尝辄止18-Linux基础-文件锁1

简介

文件锁主要有三套函数,分别是flock(2)fcntl(2)lockf(3)

函数名 实现类别 支持读锁 支持写锁 支持文件局部锁
flock FLOCK Χ Χ
lockf POSIX Χ
fcntl POSIX

从表中大概可以猜出来,lockf是用fcntl实现的库函数,不过这并不绝对,lockf与fcntl的关系并没有标准,例如在mac系统中,lockf就是劝告性锁。

代码演示

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char **argv){
    char *filename = "tmp";

    pid_t pid = fork();
    if (pid > 0){//父进程先锁文件,2s后放开
        int fd = open(filename, O_CREAT|O_RDWR, 0666);
        if (fd >= 0){
            int ret = lockf(fd, F_LOCK, 0);
            if (!ret){
                printf("[%d] locked\n", getpid());
                sleep(2);
                printf("[%d] unlocked\n", getpid());
                ret = lockf(fd, F_ULOCK, 0);
            }
            sleep(1);
            close(fd);
        }
        waitpid(pid,NULL,0);
    }
    else if (pid == 0){//子进程1s后尝试锁文件
        int fd;
        sleep(1);
        fd = open(filename, O_WRONLY);
        if (fd >= 0){
            int ret;
            printf("[%d] opened\n", getpid());
            ret = lockf(fd, F_TLOCK, 0);
            if (ret) printf("[%d] lockf fail, %s\n", getpid(), strerror(errno));
            ret = write(fd, filename, sizeof(filename));
            if (ret == sizeof(filename)) printf("[%d] write success\n", getpid());
            else printf("[%d] lockf fail, %s\n", getpid(), strerror(errno));
            ret = lockf(fd, F_LOCK, 0);
            if (!ret){
                printf("[%d] locked\n", getpid());
                ret = write(fd, filename, sizeof(filename));
                if (ret == sizeof(filename)) printf("[%d] write success\n", getpid());
                else printf("[%d] lockf fail, %s\n", getpid(), strerror(errno));
                printf("[%d] unlocked\n", getpid());
                ret = lockf(fd, F_ULOCK, 0);
            }
            close(fd);
        }
        exit(EXIT_SUCCESS);
    }
    return 0;
}

输出

[5165] locked
[5166] opened
[5166] lockf fail, Resource temporarily unavailable
[5166] write success
[5165] unlocked
[5166] locked
[5166] write success
[5166] unlocked

在父进程上锁后,子进程分别进行了非阻塞申请锁和阻塞申请锁,非阻塞申请立刻返回错误,阻塞申请就一直等到父进程释放。

为什么子进程没拿到锁,也同样写入成功了?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容