繁体   English   中英

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

[英]fcntl how to know which process hold lock file?

我是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 )。

从示例代码中:

printf ("locking\n");
/* Initialize the flock structure. */
memset (&lock, 0, sizeof(lock));
lock.l_type = F_WRLCK;
/* Place a write lock on the file. */
fcntl (fd, F_SETLKW, &lock);

printf ("locked; hit Enter to unlock... ");

您需要更改fcntl (fd, F_SETLKW, &lock); 至:

if (fcntl (fd, F_SETLK, &lock) == -1) {
  printf ("File is locked by pid %i\n", lock.l_pid);
  return 0;
}

如果无法获得锁定,则F_SETLKW命令将阻塞。 如果无法获得锁,则F_SETLK将返回。 确实,代码在获得-1返回值之后还应该检查errno == EACCESSerrno == EAGAIN

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM