unlink rm close

Posted 坐看云起时

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unlink rm close相关的知识,希望对你有一定的参考价值。

  目前看以前的代码想到一个问题,unlink  rm 区别 和和 close 的区别!

主要场景是  想使用 文件大内核锁进行多进程互斥!

多进程中使用 文件锁互斥方式如下:

mtx->fd = open_file(file_name);
mtx->name = file_name;
fork()

 也就是fork 后 进程都用这个文件的fd 然后根据文件fd 的文件锁进行互斥访问!!

当然 多进程 访问 fd 的文件锁时 可以根据需要 设置不同的获取锁规则!比如 可以实现类似于spin_lock  try_lock的动作 

trylock_fd(fd_t fd)
{
    struct flock  fl;

    memzero(&fl, sizeof(struct flock)); //这个文件锁并不用于锁文件中的内容,填充为0
    fl.l_type = F_WRLCK; 
    fl.l_whence = SEEK_SET; 
    /*
    使用F_SETLK   lock_fd方法获取互斥锁成功时会返回0,否则返回的其实是errno错误码,而这个错误码为NGX- EAGAIN或者NGX EACCESS时
    表示当前没有拿到互斥锁,否则可以认为fcntl执行错误。
     */
    if (fcntl(fd, F_SETLK, &fl) == -1) {
        return ngx_errno;
    }
    return 0;
}

/*
lock_fd方法将会阻塞进程的执行
*/
lock_fd(fd_t fd)
{
    struct flock  fl;
    memzero(&fl, sizeof(struct flock));
    //F_SETLKW  会导致进程睡眠
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;

    //如果返回-1,则表示fcntl执行错误。一旦返回0,表示成功地拿到了锁
    if (fcntl(fd, F_SETLKW, &fl) == -1) {
        return ngx_errno;
    }
    return 0;
}

参考文件:https://man7.org/linux/man-pages/man2/fcntl.2.html

 F_SETLK (struct flock *)
              Acquire a lock (when l_type is F_RDLCK or F_WRLCK) or
              release a lock (when l_type is F_UNLCK) on the bytes
              specified by the l_whence, l_start, and l_len fields of
              lock.  If a conflicting lock is held by another process,
              this call returns -1 and sets errno to EACCES or EAGAIN.
              (The error returned in this case differs across
              implementations, so POSIX requires a portable application
              to check for both errors.)

       F_SETLKW (struct flock *)
              As for F_SETLK, but if a conflicting lock is held on the
              file, then wait for that lock to be released.  If a signal
              is caught while waiting, then the call is interrupted and
              (after the signal handler has returned) returns
              immediately (with return value -1 and errno set to EINTR;
              see signal(7)).

 man7 中可以看到解释!!

由于此时只是需要多进程的互斥 所以一般是 open fd 后 就回调用unlink 删除此文件!!

对于 守护进程中使用 文件锁 来保证 单一进程拉起时, 此时不需要删除文件!!

 对于 unlink 和 rm  close 关系 

下面是来之网上的一段话!!认为是对的 !!

 

  每一个文件,都可以通过一个struct stat的结构体来获得文件信息,其中一个成员st_nlink代表文件的链接数。当通过shell的touch命令或者在程序中open一个带有O_CREAT的不存在的文件时,文件的链接数为1。

 

        通常open一个已存在的文件不会影响文件的链接数。open的作用只是使调用进程与文件之间建立一种访问关系,即open之后返回fd,调用进程可以通过fd来read 、write 、 ftruncate等等一系列对文件的操作。

 

        close()就是消除这种调用进程与文件之间的访问关系。自然,不会影响文件的链接数。在调用close时,内核会检查打开该文件的进程数,如果此数为0,进一步检查文件的链接数,如果这个数也为0,那么就删除文件内容!!
   link函数创建一个新目录项,并且增加一个链接数
        unlink函数删除目录项,并且减少一个链接数。如果链接数达到0并且没有任何进程打开该文件,该文件内容才被真正删除
如果在unlilnk之前没有close,那么依旧可以访问文件内容。

 

 对于 rm 和unlink的区别!

见这篇文章:https://unix.stackexchange.com/questions/151951/what-is-the-difference-between-rm-and-unlink

  POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn\'t a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.

rm is a traditional Unix command which has a bit of other functionality, and isn\'t quite a superset of unlink (see below).

Firstly, rm performs safety checks. If you try to rm an object to which you don\'t have write permissions (which are irrelevant to your ability to remove it: the containing directory\'s permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn\'t exist, as does unlink; however with -frm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn\'t fail when there is nothing to remove.

Secondly, rm has the -i option for interactively confirming the delete.

Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn\'t required to do, since the C library function doesn\'t do that.

The unlink utility isn\'t exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.

 

以上是关于unlink rm close的主要内容,如果未能解决你的问题,请参考以下文章

Linux之rm命令

Linux 使用 rm 命令删除文件或目录

[未解决问题记录]python asyncio+aiohttp出现Exception ignored:RuntimeError('Event loop is closed')(代码片段

unlink/file_exists 和文件未找到

如何使用 fs.unlink 删除本地文件?

在tp里面怎么使用unlink函数删除上传的图片文件?