fcntl函数之文件锁 F_SETLKW

fcntl函数之文件锁 F_SETLKW
F_SETLK与F_SETLKW的区别:
F_SETLK设的锁遇到锁被其他进程占用时,会立刻停止进程。
F_SETLKW上锁是阻塞方式。设置的锁因为其他锁而被阻止设置时,该命令会等待相冲突的锁被释放。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

/**
*
*./myfcntl content type



           struct flock {
               ...
               short l_type;     F_RDLCK,F_WRLCK,F_UNLCK
               short l_whence;   How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
               off_t l_start;    Starting offset for lock
               off_t l_len;      Number of bytes to lock
               pid_t l_pid;      PID of process blocking our lock (set by F_GETLK and F_OFD_GETLK)
               ...
           };

*
*/
int lock_reg(int fd, int cmd, short lock_type, short lock_whence, off_t lock_start, off_t lock_len)
{
        struct flock lock;
        lock.l_type = lock_type;
        lock.l_whence = lock_whence;
        lock.l_start = lock_start;
        lock.l_len = lock_len;
        lock.l_pid = getpid();

        if (fcntl(fd, cmd, &lock) < 0) {
                if (errno == EACCES || errno == EAGAIN ) {
                        printf("file lock by other processes.\n");
                        return -1;
                }
                printf("lock file fail.\n");
                return -1;
        }
        if (lock_type == F_WRLCK) {
                printf("lock by %d.\n", getpid());
        } else if (lock_type == F_UNLCK) {
                printf("unlock by %d.\n", getpid());
        }
        return 0;
}

int reg_lock(int fd)
{
        return lock_reg(fd, F_SETLK, F_WRLCK, 0, SEEK_SET, 0);
}
int reg_unlock(int fd)
{
        return lock_reg(fd, F_SETLK, F_UNLCK, 0, SEEK_SET, 0);
}

int reg_lockw(int fd)
{
        return lock_reg(fd, F_SETLKW, F_WRLCK, 0, SEEK_SET, 0);
}
int reg_unlockw(int fd)
{
        return lock_reg(fd, F_SETLKW, F_UNLCK, 0, SEEK_SET, 0);
}


/*
*
*.myfcntl AAAAAA
*/
int main(int argv, char *argc[])
{
        char *buf;
        int i;
        int ret;
        int fd;

        if (argv < 2) {
                printf("argc error!\n");
                return -1;
        }
        fd = open("processes.txt", O_CREAT|O_RDWR|O_APPEND, 777);
        ret = reg_lockw(fd);
        if (ret !=0 ) {
                return -1;
        }
        sleep(5);
        buf = argc[1];
        i = 0;
        while (i < strlen(buf)) {
                if (write(fd, buf+i, sizeof(char)) < sizeof(char)) {
                        printf("printf out error!\n");
                        return -1;
                }
                        printf(" %c:out by pid %d.\n", buf[i], getpid());
                i++;
                sleep(1);
        }
        ret = reg_unlockw(fd);
        if (ret !=0 ) {
                return -1;
        }
        close(fd);
        return 0;
}

同时运行两个进程,第二个被阻塞不退出,直到第一个进程解锁,第二个进程再上锁。
#结果
lock by 18687.
B:out by pid 18687.
B:out by pid 18687.
B:out by pid 18687.
B:out by pid 18687.
B:out by pid 18687.
B:out by pid 18687.
B:out by pid 18687.
unlock by 18687.
lock by 18686.
A:out by pid 18686.
A:out by pid 18686.
A:out by pid 18686.
A:out by pid 18686.
A:out by pid 18686.
A:out by pid 18686.
A:out by pid 18686.
unlock by 18686.
fcntl分为建议锁和强制性锁,默认是建议锁模式,该模式下,一个文件被一个进程锁住后,第二个进程是能直接往这个文件写数据的。建议每次输入数据前都有个上锁操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

spark'code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值