我是 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/