Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
fcntl如何知道哪个进程持有锁定文件?_C_Fcntl - Fatal编程技术网

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

fcntl如何知道哪个进程持有锁定文件?,c,fcntl,C,Fcntl,我是fcntl锁的新手,下面的示例使用c代码在linux中创建一个示例锁: 我想知道如何打印出哪个进程持有锁文件,哪个进程正在等待锁。我考虑使用LPID来找出持有锁的进程ID,但我不确定是否正确。 打印哪个进程持有锁的最佳方式是什么?来自示例代码: printf ("locking\n"); /* Initialize the flock structure. */ memset (&lock, 0, sizeof(lock)); lock.l_type = F_WRLCK; /* Pl

我是fcntl锁的新手,下面的示例使用c代码在linux中创建一个示例锁:

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

来自示例代码:

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==EACCESS
errno==EAGAIN

来自示例代码:

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==EACCESS
errno==EAGAIN

如页面所述,您可以使用
F\u 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
memebers是不必要的,但我宁愿在这里犯错误,谨慎一点

至于如何报告,我只想使用

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. */
intfd;
pid_t p;
fd=开放(路径,O|RDWR | O|NOCTTY);
如果(fd==-1){
fprintf(stderr,“%s:无法打开文件:%s。\n”,
路径,strerror(errno));
退出(退出失败);
}
p=锁紧(fd);
if(p<0){
fprintf(stderr,“%s:无法锁定文件:%s。\n”,
路径,strerror(errno));
退出(退出失败);
}否则
如果(p>0){
fprintf(stderr,“%s:文件已被进程%ld锁定。\n”,
路径(长)p);
退出(退出失败);
}
/*fd现在处于打开状态且独占锁定状态*/
用户可以始终运行例如
ps-o cmd=-p PID
来查看这是什么命令(或者您可以尝试在Linux中读取
/proc/PID/cmdline

如页面所述,您可以使用
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
memebers是不必要的,但我宁愿在这里犯错误,谨慎一点

至于如何报告,我只想使用

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. */
intfd;
pid_t p;
fd=开放(路径,O|RDWR | O|NOCTTY);
如果(fd==-1){
fprintf(stderr,“%s:无法打开文件:%s。\n”,
路径,strerror(errno));
退出(退出失败);
}
p=锁紧(fd);
if(p<0){
fprintf(stderr,“%s:无法锁定文件:%s。\n”,
路径,strerror(errno));
退出(退出失败);
}否则
如果(p>0){
fprintf(stderr,“%s:文件已被进程%ld锁定。\n”,
路径(长)p);
退出(退出失败);
}
/*fd现在处于打开状态且独占锁定状态*/

用户可以始终运行例如
ps-o cmd=-p PID
来查看这是什么命令(或者您可以尝试在Linux中读取
/proc/PID/cmdline

Hi,如果我这样更改代码,我会将其打印为“文件被PID 0锁定”。而且,两个进程同时被“锁定”。嗨,如果我像那样更改代码,我会将其打印为“文件被pid 0锁定”。而且,这两个过程同时被“锁定”。@AnttiHaapala抱歉,我改变了问题OK,一句话让问题更清楚了:D@AnttiHaapala对不起,我把问题改了好吧,一句话就清楚多了:谢谢。如果部分(fcntl(fd,F_GETLK,&lock)=0&&lock.l_pid>0)工作得很好!谢谢如果部分(fcntl(fd,F_GETLK,&lock)=0&&lock.l_pid>0)工作得很好!