zoukankan      html  css  js  c++  java
  • 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.

    http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子
  • 相关阅读:
    SSM知识点与整合之Spring知识点(pom.xml需要依赖的jar或者plugin)
    Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第十三集之Redis的单机版搭建】
    maven pom.xml(公司版)
    spring开发需要的配置文件
    Python socket编程之六:多窗口的应用
    subplot的应用
    Python socket编程之五:更新分时图
    Python序列的切片操作与技巧
    Python socket编程之四:模拟分时图
    NSNotificationCenter 注意
  • 原文地址:https://www.cnblogs.com/codestack/p/14804560.html
Copyright © 2011-2022 走看看