`
tomotoboy
  • 浏览: 166819 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

文件共享

阅读更多
UNIX支持在不同进程间共享打开文件,本文主要对以下几个方面简单介绍:
  • 原子操作;
  • 再次介绍dup与dup2;
  • fcntl函数;
  • ioctl函数;
  • /dev/fd;

1.介绍一下内核用于所有I/O的数据结构
内核使用了三种数据结构,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
(1) 每个进程在进程表中都有一个记录项,每个记录项中有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:
(a) 文件描述符标志。
(b) 指向一个文件表项的指针。


(2) 内核为所有打开文件维持一张文件表。每个文件表项包含:
(a) 文件状态标志(读、写、增写、同步、非阻塞等)。
(b) 当前文件位移量。
(c) 指向该文件v节点表项的指针。


(3) 每个打开文件(或设备)都有一个 v节点结构。
v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。对于大多数文件, v节点还包含了该文件的 i节点(索引节点) 。这些信息是在打开文件时从盘上读入内存的,所以所有关于文件的信息都是快速可供使用的。例如, i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件在盘上所使用的实际数据块的指针等等。

图1显示了进程的三张表之间的关系。该进程有两个不同的打开文件——一个文件打开为标准输入(文件描述符0) ,另一个打开为标准输出(文件描述符为1) 。

图1:打开文件的内核数据结构


如果两个独立进程各自打开了同一文件,则有图2中所示的安排:

图2:两个独立进程各自打开同一个文件

我们假定第一个进程使该文件在文件描述符 3上打开,而另一个进程则使此文件在文件描述符 4上打开。打开此文件的每个进程都得到一个文件表项,但对一个给定的文件只有一个 v节点表项。每个进程都有自己的文件表项的一个理由是:这种安排使每个进程都有它自己的对该文件的当前位移量。

2.原子操作
所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。
单处理器中,在多进程(线程)访问资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源。

3.dup与dup2
#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
两函数的返回:若成功为新的文件描述符,若出错为- 1

由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则先将其关闭。如若filedes等于filedes2,则dup2返回filedes2,而不关闭它。这些函数返回的新文件描述符与参数filedes共享同一个文件表项。

每个文件描述符都有它自己的一套文件描述符标志。正如我们将在下一节中说明的那样,新描述符的执行时关闭( close-on-exec )文件描述符标志总是由dup函数清除。复制一个描述符的另一种方法是使用 fcntl函数,下一节将对该函数进行说明。实际上,
调用:
dup (filedes ) ;
等效于:
fcntl (filedes, F_DUPFD, 0);
而调用:
dup2(filedes, filedes2) ;

等效于:
close(filedes2) ;
fcntl(filedes, F_DUPFD, filedes2);
在最后一种情况下,dup2并不完全等同于close加上fcntl。它们之间的区别是:
(1) dup2是一个原子操作,而close及fcntl则包括两个函数调用。有可能在close和fcntl之间插入执行信号捕获函数,它可能修改文件描述符。
(2) 在dup2和fcntl之间有某些不同的errno。


4.fcntl函数
fcntl函数可以改变已经打开文件的性质。
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int fcntl(int filedes, int cmd ,…/*int arg*/ );
返回:若成功则依赖于cmd(见下),若出错为-1
在《unix环境高级编程》中提到:一般第三个参数是一个整数,与上面所示函数原型中的注释部分相对应。但是在书中提到在说明记录锁时,第三个参数则是指向一个结构的指针。
fcntl函数有五种功能:
  • 复制一个现存的描述符(cmd=F_DUPFD)
  • 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)
  • 获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)
  • 获得/设置异步I/O有权(cmd=F_GETOWN或F_SETOWN)
  • 获得/设置记录锁(cmd=F_GETLK , F_SETLK或F_SETLKW)

  • F_DUPFD 复制文件描述符filedes, 新文件描述符作为函数值返回。它是尚未打开的各描述符中大于或等于第三个参数值(取为整型值)中各值的最小值。新描述符与 filedes 共享同一文件表项 。但是,新描述符有它自己的一套文件描述符标志,其 FD_CLOEXEC文件描述符标志则被清除。
  • F_GETFD   对应于filedes 的文件描述符标志作为函数值返回。当前只定义了一个文件描述符标志FD_CLOEXEC。
  • F_SETFD   对于filedes 设置文件描述符标志。新标志值按第三个参数(取为整型值)设置。
  • 应当了解很多现存的涉及文件描述符标志的程序并不使用常数 FD_CLOEXEC,而是将此标志设置为0 (系统默认,在exec时不关闭)或1 (在exec时关闭)。
  • F_GETFL   对应于filedes 的文件状态标志作为函数值返回。在说明open函数时,已说明了文件状态标志,如图3所示:

图3:对于fcntl的文件状态标志

不幸的是,三个存取方式标志( O_RDONLY, O_WRONLY,以及O_RDWR )并不各占1位。(正如前述,这三种标志的值各是 0、1和2,由于历史原因。这三种值互斥—一个文件只能有这三种值之一。)因此首先必须用屏蔽字O_ACCMODE取得存取方式位,然后将结果与这三种值相比较。[list]
  • F_SETFL   将文件状态标志设置为第三个参数的值(取为整型值)。 可以更改的几个标志是:O_APPEND,O_NONBLO CK,O_SYNC和O_ASYNC。
  • F_GETOWN   取当前接收SIGIO和SIGURG信号的进程I D或进程组ID。
  • F_SETOWN   设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定一个进程ID,负的arg表示等于arg绝对值的一个进程组 D。
  • [/list]fcntl的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD,F_GETFD, F_GETFL以及F_GETOWN。第一个返回新的文件描述符,第二个返回相应标志,最后一个返回一个正的进程I D或负的进程组ID。
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <fcntl.h>
    int main(int argc, char *argv[])
    {
       int accmode, val;
       if(argc !=2){
         printf("usage:  pro_2 <descriptor#>");
         exit(1);
        }
       if((val=fcntl(atoi(argv[1]),F_GETFL,0))<0)
        {
            printf("fcntl error for fd %d",atoi(argv[1]));
            exit(1);
       }
        accmode=val&O_ACCMODE;
        if(accmode==O_RDONLY) printf("read only");
        else if(accmode==O_WRONLY) printf("write only");
        else if(accmode==O_RDWR) printf("read write");
        else{
            printf("unknown access mode");
            exit(1);
         }
          if(val & O_APPEND) printf(", append");
          if(val & O_NONBLOCK) printf(", nonblocking");
       #if !defined(_POSIX_SOURCE)&&defined(O_SYNC)
           if(val&O_SYNC) printf(", synchronous writes");
       #endif
          putchar('\n');
          exit(0);
    
    }

    /home/l/g/tomotoboy/io >gcc pro_2.c -o pro_2
    /home/l/g/tomotoboy/io >pro_2 0 </dev/tty
    read only
    /home/l/g/tomotoboy/io >pro_2 2 2>temp.foo
    write only
    /home/l/g/tomotoboy/io >pro_2 2 2>>temp.foo
    write only, append


    一个对于一个文件描述符设置一个或多个文件状态标志的函数
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <fcntl.h>
    void set_fl(int fd, int flags) /* flags are file status flags to turn on*/
    {
    	int val;
    	if((val = fcntl(fd, F_GETFL ,0))<0){
    		printf("fcntl FGETFL error");
    		exit(1);
                    }
    	val |=flags; /* turn on flags */
     	if(fcntl(fd, F_SETFL ,val)<0){
    		printf("fcntl F_SETFL error");
    		exit(1);
    	}
    }

    如果将中间的一条语句改为:
    val &= ˜flags;        /*turn flags off*/

    就构成了另一个函数,我们称其为 clr_ fl,并将在后面某个例子中用到它。此语句使当前文件状态标志值val与flags的反码逻辑与运算。如果在程序pro_3的开始处,加上下面一行以调用set_fl,则打开了同步写标志。
    set_fl(STDOUT_FILENO, O_SYNC);

    这就造成每次write都要等待,直至数据已写到磁盘上再返回。

    5.ioctl函数


    6./dev/fd
    比较新的系统都提供名为/dev/fd的目录,其目录项是名为 0、1、2等的文件。打开文件/dev/fd /n等效于复制描述符n (假定描述符n是打开的)。




    参考质料
    《UNIX环境高级编程》
    百度百科-原子操作
    Linux原子操作
    • 大小: 19.3 KB
    • 大小: 22.3 KB
    • 大小: 11.8 KB
    分享到:
    评论

    相关推荐

      HTTP文件共享小工具

      HTTP文件共享小工具是一款便捷高效的文件分发和共享解决方案,尤其适合在局域网或互联网环境中快速分享大文件。这款小软件以其简单的设置流程、快速的传输速度和出色的稳定性赢得了用户的青睐。 首先,我们来了解...

      WIN 10因为文件共享不安全,所以你不能连接到文件共享.docx

      ### Windows 10 文件共享不安全问题解析及解决方法 #### 一、问题概述 在使用Windows 10操作系统访问共享文件时,可能会遇到“因为文件共享不安全,所以你不能连接到文件共享”的提示。这主要是由于系统默认禁用了...

      Windows2016文件共享设置配额

      在Windows Server 2016操作系统中,文件共享配额是一项重要的管理功能,它允许管理员控制用户或特定文件夹的存储使用量。设置配额的主要目的是有效地管理存储资源,防止个别用户或文件夹过度占用存储空间,从而影响...

      linux文件共享服务汇总

      Linux 文件共享服务是将Linux系统中的文件和目录暴露给网络中的其他系统,以便进行数据交换和协作。在Linux中,有几种主要的文件共享服务,包括Samba、FTP(使用vsftpd)以及NFS(网络文件系统)。下面将详细介绍...

      联想工程师专用小工具 文件共享工具V3.52.1

      联想工程师专用小工具 文件共享工具V3.52.1联想工程师专用小工具 文件共享工具V3.52.1联想工程师专用小工具 文件共享工具V3.52.1联想工程师专用小工具 文件共享工具V3.52.1联想工程师专用小工具 文件共享工具V3.52.1...

      一个基于django实现的轻量级文件共享系统源码.zip

      一个基于django实现的轻量级文件共享系统源码 一个基于django实现的轻量级文件共享系统源码 一个基于django实现的轻量级文件共享系统源码 一个基于django实现的轻量级文件共享系统源码 一个基于django实现的轻量...

      Python 实现局域网内文件共享功能

      在局域网内实现文件共享功能,Python提供了多种方法,其中最基础的是使用内置的`sockets`模块。本篇文章将详细探讨如何使用Python的sockets模块来创建一个简单的局域网文件共享系统。 首先,我们要了解局域网文件...

      虚拟机LINUX与主机WINDOWS文件共享

      虚拟机 LINUX 与主机 WINDOWS 文件共享 在虚拟机 LINUX 和主机 WINDOWS 之间实现文件共享需要使用 SAMBA 服务器。 SAMBA 是一个功能强大的开源软件,可以实现 LINUX 和 WINDOWS 之间的文件共享。下面将详细介绍如何...

      操作系统安全:文件共享安全设置.pptx

      操作系统安全是IT领域中至关重要的一个方面,尤其是在文件共享时,确保数据安全是维护系统稳定性和用户隐私的关键。本文将详细探讨文件共享安全设置的重要性、方法以及如何在Windows操作系统中实施有效的安全策略。 ...

      阡陌局域网文件共享软件

      阡陌局域网文件共享软件是一款专为解决局域网内文件共享问题而设计的应用程序。在Windows操作系统环境中,设置文件夹共享往往涉及到复杂的网络配置和权限设定,这对于普通用户来说可能较为困难,而且不同版本的...

      Wormhole虫洞文件共享v1.3.0,无须上传网盘、不必发送文件,一键创建共享点对点链接.rar

      《Wormhole虫洞文件共享:点对点高效文件传输技术解析》 在数字化时代,文件的快速分享和传输成为了日常工作中不可或缺的一部分。Wormhole虫洞文件共享工具以其独特的v1.3.0版本,为用户提供了无需上传网盘、无需...

      php实现文件共享(其于windows网上邻居原理)

      php实现文件共享(其于windows网上邻居原理)  通过本php文件,在进行相关设置后,您可以方便的看到共享目录中的文件,以及相应的说明,便于能够迅速找到自己想要的文件。  找到想要的东西后,直接点击文件夹名打开...

      -远程文件共享工具-

      标题中的“-远程文件共享工具-”指的是用于在网络上分享文件的工具,这类工具允许用户将本地计算机上的文件通过网络提供给他人访问或下载。在描述中提到的功能是生成临时网址,然后将这个网址发送给朋友,使他们...

      基于Linux和windows之间文件共享网络服务研究.pdf

      "基于Linux和windows之间文件共享网络服务研究" 本文研究了基于Linux和Windows之间文件共享网络服务,解决了Linux和Windows操作系统之间文件共享的问题。论文中介绍了使用Samba服务来实现文件共享,详细介绍了Samba...

      p2p文件共享程序

      【标题】:“p2p文件共享程序” 【描述】:“p2p文件共享程序 java课程设计 java设计……” 本文将详细解析基于Java实现的P2P(peer-to-peer)文件共享程序的设计与实现,这是一种利用互联网技术让网络中的每个...

      在VMware的ubuntu虚拟机中实现和Windows文件共享

      ### 在VMware的Ubuntu虚拟机中实现与Windows文件共享 #### 环境配置与准备工作 在本教程中,我们将详细介绍如何在VMware Workstation环境下搭建一个Ubuntu虚拟机,并实现Ubuntu虚拟机与宿主机(假设为Windows操作...

      delphi局域网文件共享源码

      - 在局域网内实现文件共享,一般可以采用SMB(Server Message Block)协议,这是一种由Microsoft开发的网络文件共享协议,Delphi可以通过Windows API调用SMB服务进行文件共享操作。 4. **源码解析**: - "delphi...

      阡陌 3.1.8.1 局域网文件共享工具

      阡陌 3.1.8.1 局域网文件共享工具是一款专为解决传统“网上邻居”功能不便而设计的应用程序。在Windows系统中,虽然内置了“网上邻居”功能,但用户在进行局域网内的文件共享时可能会遇到速度慢、连接不稳定或操作...

      Linux系统下用samba工具实现文件共享及共享打印机的配置

      "Linux系统下用Samba工具实现文件共享及共享打印机的配置" Linux系统下用Samba工具实现文件共享及共享打印机的配置是指使用Samba工具在Linux系统下实现文件共享和共享打印机的配置,这个过程需要对Samba工具的配置...

    Global site tag (gtag.js) - Google Analytics