分享

Linux高级I/O

 书永夜 2013-11-17
一.记录锁
    1.fcntl函数实现
    注意:a.加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开。
         b.兼容性规则适用于不同进程提出的锁要求,并不适用于单个进程提出的多个锁请求。如果一个进程对一个
        文件区间已经有了一把锁,后来该进程又企图在同一文件区间再加一把锁,那么新锁将替换老锁。若一进
        程在某文件的16~32字节区加一把写锁,然后又试图在16~32字节区间加一把读锁,那么请求将成功
        执行,原来的写锁被替换为读锁。
         c.锁的隐含继承和释放:
         1>.锁与进程和文件两方面有关系,它和前者关系是:当一个进程结束后,他对文件加的锁也就消
        失了。它和后者的关系是:当进程 close 文件描述符,切断文件和进程的联系进程所创建的锁也会消失。

         2>.由 fork 产生的子进程不继承父进程所设置的锁。这意味着,若一个进程得到一把锁,然后调用 fork,
            那么对于父进程创建的锁而言,子进程被视为另一个进程,不会拥有该锁。

         3>.在执行 exec 后,新进程可以继承原执行的锁。因为执行 exec 前后还是一个进程。我们只是改变进程
            执行的程序,并没有创建新的进程。
         d.对于同一个文件描述符,在兼容性规则下,多个进程对这个文件加锁的区域没有交集,就不会产生互斥。
         e.对于同一个文件描述符,在兼容性规则下,只要多个进程对这个文件加锁的区域有交集,就会互斥,
        即互相阻塞。

二.I/O多路转接
    #include<sys/select.h>
    int select(int maxfds,fd_set *restrict readfds,fd_set_set *restrict writefds,
        fd_set *restrict exceptfds,struct timeval *restrict tvptr);
        返回值:准备就绪的描述符数,若超时则返回0,若出错则返回-1.
    struct timeval
    {
        long tv_sec;/*seconds*/
        long tv_usec;/*microseconds*/
    }
    有三种情况:
    tvptr == NULL 永远等待
    tvptr->tv_sec == 0 && tvptr->usec == 0 完全不等待,这是得到多个描述符的状态而不阻塞select函数的
        轮询方法。
    tv->tv_sec != 0 || tvptr->usec != 0 等待指定的秒数和微秒数。

    int FD_ISSET(int fd,fd_set *fdset);//判断描述符是否在监听集中,若在返回非0值,否则返回0
    void FD_CLR(int fd,fd_set *fdset);//将一文件描述符指定位从监听集中清除
    void FD_SET(int fd,fd_set *fdset);//将文件描述符加入监听集,设置一个fd_set变量的指定位。
    void FD_ZERO(fd_set *fdset);//清空监听集


    #include<poll.h>
    int poll(struct pollfd fdarray[],nfds_t nfds,int timeout);
                返回值:准备就绪的描述符数,若超时返回0,若出错返回-1.
    struct pollfd
    {
        int fd;
        short events; /*events of interest on fd*/
        short revents;/*events that occurred on fd*/
    };
    //设置events所关心的状态标志,调用poll函数,内核设置revents成员,说明对于该描述符已发生什么事件。
        
    timeout == -1 永远等待
    timeout == 0 不等待
    timeout > 0 等待timeout毫秒

三.异步I/O
    在BSD派生的系统中,异步I/O是SIGIO和SIGURG两个信号的组合。前者通用,后者用来通知进程在网络连接上到达
    了带外的数据。为了接收SIGIO信号,需执行下列三部:
    (1)调用signal或sigaction为SIGIO信号建立信号处理程序。
    (2)以命令F_SEOWN调用fcntl来设置进程ID和进程组ID,它们将接收对于该描述符的信号。
    (3)以命令F_SETFL调用fcntl设置O_ASYNC文件状态标志,使在该描述符上可以进行异步I/O。

四.存储映射I/O
    使一个磁盘文件与存储空间中的一个缓冲区相映射。于是从缓冲区取数据,就相当于读文件中的相应字节。
    #include<sys/mman.h>
    void *mmap(void *addr,size_t len,int prot,int flag,int filedes,off_t off);
            返回值:若成功则返回映射区的起始地址,若出错则返回MAP_FAILED.
    addr == NULL表示由系统选择该映射区的起始地址。
    filedes:指定要被映射的描述符。首先要带开该文件
    len:是映射的字节数。
    off:是要映射字节在文件中的起始偏移量
    prot:参数说明对映射存储区的保护要求
    flag:参数影响映射存储区的多种属性
    注意:进程终止时,或调用了munmap之后,存储映射区就被自动解除映射。关闭文件描述符filedes并不解除映
    射区。
    #include<sys/mman.h>
    int munmap(caddr_t addr,size_t len);
            返回值:若成功则返回0,出错则返回-1。

    

    






    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多