c - fcntl如何知道哪个进程持有锁文件?

标签 c fcntl

我是 fcntl 锁定的新手,并按照此示例使用 C 代码在 Linux 中创建示例锁:http://www.informit.com/articles/article.aspx?p=23618&seqNum=4

我想知道我们如何才能打印出哪个进程持有锁文件以及哪个进程正在等待锁。我考虑使用 l_pid 来找出持有锁的进程 ID,但我不确定正确的方法。 打印出哪个进程持有锁的最佳方法是什么?

最佳答案

作为man 2 fcntl页面描述,您可以使用F_GETLK 获取具有冲突锁的进程ID(如果冲突锁是进程关联的)。所以,例如,

/* Return 0 if descriptor locked exclusively, positive PID if
   a known process holds a conflicting lock, or -1 if the
   descriptor cannot be locked (and errno has the reason).
*/
static pid_t  lock_exclusively(const int fd)
{
    struct flock  lock;
    int           err = 0;

    if (fd == -1) {
        errno = EINVAL;
        return -1;
    }

    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;
    if (!fcntl(fd, F_SETLK, &lock))
        return 0;

    /* Remember the cause of the failure */
    err = errno;

    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;
    lock.l_pid = 0;
    if (fcntl(fd, F_GETLK, &lock) == 0 && lock.l_pid > 0)
        return lock.l_pid;

    errno = err;
    return -1;
}

请注意,fd 必须打开以进行读写。我建议使用 open(path, O_RDWR | O_NOCTTY)open(path, O_WRONLY | O_NOCTTY)。关闭同一文件的任何文件描述符将释放锁。

有些人可能会说在第二次 fcntl() 调用之前重新设置 lock 成员是不必要的,但我宁愿在这里谨慎行事。

至于怎么报,我就直接用

int    fd;
pid_t  p;

fd = open(path, O_RDWR | O_NOCTTY);
if (fd == -1) {
    fprintf(stderr, "%s: Cannot open file: %s.\n",
                    path, strerror(errno));
    exit(EXIT_FAILURE);
}

p = lock_exclusively(fd);
if (p < 0) {
    fprintf(stderr, "%s: Cannot lock file: %s.\n",
                    path, strerror(errno));
    exit(EXIT_FAILURE);
} else
if (p > 0) {
    fprintf(stderr, "%s: File is already locked by process %ld.\n",
                    path, (long)p);
    exit(EXIT_FAILURE);
}

/* fd is now open and exclusive-locked. */

用户总是可以运行例如ps -o cmd= -p PID 查看是什么命令(或者您可以尝试阅读 Linux 中的 /proc/PID/cmdline)。

关于c - fcntl如何知道哪个进程持有锁文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51388456/

相关文章:

c fwrite() 写入仅包含一个结构变量的文件?

c - 整数常量指向的对象的默认类型

c - C程序中的字符串文字,可以在二进制中找到吗?

python - 管道 ("bitwise OR") 调用 fcntl.lockf()

linux - C++串口通信读数据有效但写入失败

c - If-else block 和 float 数据类型的意外结果。 [编辑了一个问题]

c - 字符串 "Putty"的奇怪出现

python - fcntl.lockf() 以何种方式锁定文件?

c - fcntl() 关于进程id的问题