系统编程(五)文件IO之常用API fcntl

系统调用文件IO存在线程安全的问题,当多个用户共同使用、操作一个文件的时候,Linux 通常采用的方法是给文件上锁,来避免共享资源产生竞争的状态。
文件锁可以分为共享读锁和独占写锁。共享读锁:文件必须使用只读打开,一个进程上了读锁,其他进程还可以上读锁,此时,无法进行写操作。独占写锁:文件必须受用只写打开,一个进程上了写锁,其他进程就不能上读写锁了,这就是读写互斥。
这里我们依旧用上一节的fcntl函数。

int fcntl(int fd, int cmd, struct flock *lock);
struct flock {
    short l_type;                /* F_RDLCK, F_WRLCK, or F_UNLCK */
    short l_whence;                /* SEEK_SET, SEEK_CUR, SEEK_END */
    __kernel_off_t    l_start;    
    __kernel_off_t    l_len;
    __kernel_pid_t    l_pid;
    __ARCH_FLOCK_PAD

};

下面给出一段代码,可以测试互斥写和共享读锁,测试的时候需要开两个中端,这样才能看出来效果。代码是从这位博主那抄来的(https://www.cnblogs.com/mingfeng002/p/6962915.html),今天心情有些不好,以后有时间单独写一个个测试代码贴过来

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

void lock_set(int fd, int type)
{
    struct flock lock;
    lock.l_whence = SEEK_SET;//赋值lock结构体
    lock.l_start = 0;
    lock.l_len = 0;
    while (1){
        lock.l_type = type;
        /*根据不同的type值给文件上锁或解锁*/
        if ((fcntl(fd, F_SETLK, &lock)) == 0){
            if (lock.l_type == F_RDLCK)
                printf("read lock set by %d\n", getpid());
            else if (lock.l_type == F_WRLCK)
                printf("write lock set by %d\n", getpid());
            else if (lock.l_type == F_UNLCK)
                printf("release lock by %d\n", getpid());
            return;
        }
        /*判断文件是否可以上锁*/
        int re = fcntl(fd, F_GETLK, &lock);
        printf("%d\n",re);
        /*判断文件不能上锁的原因*/
        if (lock.l_type != F_UNLCK){
            /*/该文件已有写入锁*/
            if (lock.l_type == F_RDLCK)
                printf("read lock already set by %d\n", lock.l_pid);
            /*该文件已有读取锁*/
            else if (lock.l_type == F_WRLCK)
                printf("write lock already set by %d\n", lock.l_pid);
            getchar();
        }
    }
}

int main(void)
{
    struct flock lock;
    pid_t pid;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;
    lock.l_type = F_RDLCK;
    int fd;

    fd = open("demo5.txt", O_RDWR | O_CREAT, 0666);
    if (fd < 0){
        perror("open");
        exit(1);
    }

    lock_set(fd, F_WRLCK);//互斥写F_WRLCK  共享读F_RDLCK   修改这里就可以测试互斥写和共享读
    getchar();
    lock_set(fd, F_UNLCK);
    getchar();
    close(fd);
    exit(0);
}

猜你喜欢

转载自blog.csdn.net/bin_zhang1/article/details/81076513