fcntl F_GETLK 总是 returns F_UNLCK

fcntl F_GETLK always returns F_UNLCK

我想了解 C 中的 POSIX 文件区域锁。下面的程序非常简单,将锁设置为 F_WRLCK 然后获取锁。 opening/setting 锁定期间没有错误。不幸的是,它总是返回 F_UNLCK。错误在哪里?它可能无法在 OSX 上正常工作吗?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
void printLockType(int lock) {
    if ( lock == F_RDLCK ) {
            printf("readlock %i \n", lock);
    }else if ( lock == F_WRLCK ) {
            printf("writelock %i \n", lock);
    }else if ( lock == F_UNLCK ) {
            printf("unlock %i \n", lock);
    } else {
            printf("other %i\n", lock);
    }
} 
int main(int argc, char *argv[])
{    
    int fd;
    struct flock fl ,fl2;

    fl2.l_type   = F_RDLCK;  /* read/write lock */
    fl2.l_whence = 0; /* beginning of file */
    fl2.l_start  = 0;        /* offset from l_whence */
    fl2.l_len    = 100;        /* length, 0 = to EOF */
    fl2.l_pid    = getpid();

    fl.l_type   = F_WRLCK;  /* read/write lock */
    fl.l_whence = 0; /* beginning of file */
    fl.l_start  = 0;        /* offset from l_whence */
    fl.l_len    = 1000;        /* length, 0 = to EOF */
    fl.l_pid    = getpid();

    if ((fd = open("xxx", O_RDWR)) == -1) {
        perror("open");
        exit(1);
    }


    if (fcntl(fd, F_SETLK, &fl) == -1) {
        perror("fcntl");
        exit(1);
    }

    if(fcntl(fd, F_GETLK, &fl2) == -1) {
        printf("%s \n", strerror(errno));
    } else {
        printLockType(fl2.l_type);
    }

    return 0;
}

您误解了 F_GETLK 查询。它 returns F_UNLCK 没有任何东西阻止调用进程在给定位置放置给定类型的锁时。

由于调用进程是创建这些现有锁的进程,它也可以创建这个新锁。


Mac OS X manuals

 F_GETLK 

Get the first lock that blocks the lock description pointed to by the third argument, arg, taken as a pointer to a struct flock (see above). The information retrieved overwrites the information passed to fcntl in the flock structure. If no lock is found that would prevent this lock from being created, the structure is left unchanged by this function call except for the lock type which is set to F_UNLCK.