[Linux]fcntl函数文件锁概述

概述

fcntl函数文件锁有几个比较容易忽视的地方:

1.文件锁是真的进程之间而言的,调用进程绝对不会被自己创建的锁锁住,因为F_SETLK和F_SETLKW命令总是替换调用进程现有的锁(若已存在),所以调用进程决不会阻塞在自己持有的锁上,于是,F_GETLK命令决不会报告调用进程自己持有的锁。

2.struct flock结构指针中的l_type成员3个short值分别是:

常量
F_RDLCK 0
F_WRLCK 1
F_UNLCK 2

 

3.如果两个锁之间的文件区域有交集,就会阻塞,无论交集的大小。

 

如图中section 1持有1到10字节区间的读锁,倘若此时需要创建section 2写锁,那么需要等待section 1区域释放才行。

示例代码:

进程A

#include <error.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

extern int *__errno_location(void);
#define errno (*__errno_location())

void report_err(int re);

struct flock section_1 = {
    F_RDLCK,
    SEEK_SET,
    0,
    10
};
struct flock section_1_1 = {
    F_RDLCK,
    SEEK_SET,
    0,
    10
};

int main(void)
{
    int re;
    int file = open("/documents/test/test_2", O_RDWR);
    printf("open file fd: %d\n", file);
    //struct flock section_1_1 = section_1;
    re = fcntl(file, F_GETLK, &section_1);
    printf("section_1 l_type: %d\n", (&section_1)->l_type);
    re = fcntl(file, F_SETLK, &section_1_1);
    report_err(re);
    printf("section_1_1 l_type: %d\n", (&section_1_1)->l_type);

    sleep(10);
    return 0;
}

void report_err(int re)
{
    if(re == -1){
        perror("file error");
    }
}

进程B

#include <error.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

extern int *__errno_location(void);
#define errno (*__errno_location())

void report_err(int re);


struct flock section_2 = {
    F_WRLCK,
    SEEK_SET,
    5,
    10
};
struct flock section_2_1 = {
    F_WRLCK,
    SEEK_SET,
    5,
    10
};

int main(void)
{
    int re;
    int file = open("/documents/test/test_2", O_RDWR);
    printf("open file fd: %d\n", file);

    re = fcntl(file, F_GETLK, &section_2);
    report_err(re);
    printf("section_2 l_type: %d\n", (&section_2)->l_type);
    re = fcntl(file, F_SETLKW, &section_2_1);
    report_err(re);
    printf("section_2_1 l_type: %d\n", (&section_2_1)->l_type);
    return 0;
}

void report_err(int re)
{
    if(re == -1){
        perror("file error");
    }
}

进程A在创建section 1后阻塞10秒,期间启动进程B创建section 2,此时进程B阻塞等待进程A释放section 1。

猜你喜欢

转载自www.cnblogs.com/yiyide266/p/10629624.html