文件锁flock()函数的测试

有一次在看别人的代码的时候,发现代码中的一个类,在初始化的时候使用了flock()函数对文件进行了加锁操作,然后发现在关闭文件描述符的时候,并没有调用flock函数进行解锁,我就产生了疑问,到底flock能锁住文件吗?然后就自己写了一个小程序进行了一下测试:

#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>

using namespace std;

class tflock{
public:
    tflock(int flag):_flag(flag){
        _fd = open("/root/003",O_CREAT | O_RDWR, 0666);
        if(_fd>0){
        //对文件进行加锁
            int ret = flock(_fd,LOCK_EX |LOCK_NB);
            cout<<"func = "<<_flag<<"  flock ret = "<<ret<<endl;
        }else{
            cout<<"open failed"<<endl;
            _fd  = -1;
        }
    }
    int getfd(){
        return _fd;
    }
    ~tflock(){
        if(_fd > 0){
        //析构函数对文件进行解锁
            flock(_fd,LOCK_UN);
            int clf = close(_fd);
            if(clf)
            {
                cout<<"close fd faile  clf  = "<<clf<<endl;
            }else{
            cout<<"deconstructor successed  and fd = "<<_fd<<"  and flag = "<<_flag<<endl;}
        }
    }
private:
    int     _fd;//记录文件描述符
    int     _flag;//区分一下析构函数
};

简单写一个类,然后通过使用类来操作同一个文件

void* Test(void* para){
    tflock tf(1);
    int fd = tf.getfd();
    if(fd>0){
        write(fd,"helloworld",(size_t)10);
        //因为析构函数执行解锁操作,该函数先执行,但是后析构,肯定会有写入冲突
        sleep(5);
        cout<<"Test fd = "<<fd<<"   pid = "<<(long int)para<<endl;
    }
    return NULL;
}
void* Test2(void* para){
    tflock tf(2);
    int fd = tf.getfd();
    if(fd>0){
        write(fd,"12345678901112345678",(size_t)20);
        cout<<"Test2 fd = "<<fd<<"   pid = "<<(long int)para<<endl;
    }

    return NULL;
}

int main(){

    pthread_t t1;
    pthread_t t2;
    pthread_create(&t1,NULL,Test,(void *)1);
    //保证线程1先执行
    sleep(1);
    pthread_create(&t2,NULL,Test2,(void *)2);

    pthread_join(t2,NULL);
    sleep(1);
    pthread_join(t1,NULL);

    while(1);
    return 0;
}

执行结果:

func = 1 flock ret = 0
func = 2 flock ret = -1 //第二个线程对文件加锁失败了,所以返回值是-1
Test2 fd = 4   pid = 2
deconstructor successed  and fd = 4  and flag = 2//第二个函数先析构
Test fd = 3   pid = 1//fd不同,说明函数2重新打开文件,生成了一个新的文件描述符来对文件进行操作
deconstructor successed  and fd = 3  and flag = 1

查看文件内容发现,函数1写入的内容被覆盖了,说明flock函数,没有对文件起到加锁的作用,其他线程依然可以对文件进行操作。

在其他文章中看到了关于flock的描述:
flock,建议性锁,不具备强制性。一个进程使用flock将文件锁住,另一个进程可以直接操作正在被锁的文件,修改文件中的数据,原因在于flock只是用于检测文件是否被加锁,针对文件已经被加锁,另一个进程写入数据的情况,内核不会阻止这个进程的写入操作,也就是建议性锁的内核处理策略。

因此flock函数实际上只是给了文件多一个状态,另外的线程可以检测这个加锁的状态,可以通过检测文件是否加锁,来进行自己的逻辑处理,真要防止写入冲突,还需要进行其他的加锁操作

猜你喜欢

转载自blog.csdn.net/veghlreywg/article/details/72858481
今日推荐