zoukankan      html  css  js  c++  java
  • Linux系统调用与文件I/O(二)

    fcntl函数,可以改变已经打开文件的性质。
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int filedes,int cmd,...);
    返回:若成功则依赖于cmd,若出错则为-1

    .用fcntl给文件加锁:
     当多个用户共同使用、操作一个文件的时候,linux通常采用的方法是给文件上锁,来避免共享资源产生竞 

      争的状态.   文件锁包括建议锁和强制性锁。建议性锁要求上锁文件的进程都要检测是否有锁存在,并尊重已有  

     的锁。强制性锁由内核和系统执行的锁。
     fcntl不仅可以实现建议性锁而且可以实施强制性锁。
       >F_RDLCK---共享读锁
       >F_WRLCK---独占性写锁
       >F_UNLCK---解锁一个区域
    要加锁或解锁的区域的起始地址,由l_start和l_whence两者决定。l_start是相对位移量(字节),l_whence则决定了

    相对位移量的起点.
    区域的长度由l_len表示

    关于加锁和解锁区域的说明:
     >该区域不能在文件起始位置之前
     >若l_len为0,表示锁的区域从其起点开始直至最大可能位置为止,即文件数据都处于锁的范围
     >通常用l_start说明为0,l_whence说明为SEEK_SET,l_len说明为0来锁整个文件

    .ioctl函数:
     ioctl函数是I/O操作的杂物箱,不能用其他函数表示的I/O操作通常都能用ioctl表示。终端I/O是ioctl的最

    大使用方面,主要用于设备的I/O控制.
    #include <unistd.h>
    #include <sys/ioctl.h>
    int ioctl(int filedes,int request,...);
    返回:若出错则为-1,若成功则为其他值

    .select实现I/O复用:
     I/O处理的五种模型:
       1>阻塞I/O模型:若所调用的I/O函数没有完成相关的功能就会是进程挂起,直到相关数据到达才会返回
      如:终端、网络设备的访问
       2>非阻塞模型:当请求的I/O操作不能完成时,则不让进程休眠,而且返回一个错误
      如:open,read,write等。
       3>I/O多路转接模型:如果请求的I/O操作阻塞,且它不是真正阻塞I/O,而且让其中的一个函数等待,在这

               期间,I/O还能进行其他操作。如:select函数。
        4>信号驱动I/O模型:在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来, 

                从而启动I/O.
       5>异步I/O模型:在这种模型下,当一个描述符已准备好,可以启动I/O时,进程会通知内核,由内核进行

          后续处理 

     对文件描述符的处理主要设计4个宏函数:
     FD_ZERO(fd_set *set):清除一个文件描述符集
     FD_SET(int fd,fd_set *set)将一个文件描述符加入文件描述符集中
     FD_CLR(int fd,fd_set *set)将一个文件描述符从文件描述符集中清除
     FD_ISSET(int fd,fd_set *set)测试该集中的一个给定位是否有变化

    在使用select函数之前,首先用FD_ZERO和FD_SET初始化文件描述符集,并使用select时,可循环使用FD_ISSET测试

    描述符集,执行完成对相关的文件描述符后,使用FD_CLR来清除描述符集.
    Example: select.c

    /*select.c*/
    //每隔10秒从第一个文件中读取7个字节写入到第二个文件中
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/time.h>

    int main(void)
    {
    int fds[2];
    char buf[7];
    int i,rc,maxfd;
    fd_set inset1,inset2;
    struct timeval tv;

    if((fds[0] = open ("hello1", O_RDWR|O_CREAT,0666))<0)
    perror("open hello1");
    if((fds[1] = open ("hello2", O_RDWR|O_CREAT,0666))<0)
    perror("open hello2");
    if((rc = write(fds[0],"Hello!\n",7)))
    printf("rc=%d\n",rc);

    lseek(fds[0],0,SEEK_SET);
    maxfd = fds[0]>fds[1] ? fds[0] : fds[1];

    FD_ZERO(&inset1);
    FD_SET(fds[0],&inset1);
    FD_ZERO(&inset2);
    FD_SET(fds[1],&inset2);
    tv.tv_sec=2;
    tv.tv_usec=0;
    while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2))
    {
    if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)
    perror("select");
    else
    {
    if(FD_ISSET(fds[0],&inset1))
    {
    rc = read(fds[0],buf,7);
    if(rc>0)
    {
    buf[rc]='\0';
    printf("read: %s\n",buf);
    }
    else
    perror("read");
    }
    if(FD_ISSET(fds[1],&inset2))
    {
    rc = write(fds[1],buf,7);
    if(rc>0)
    {
    buf[rc]='\0';
    printf("rc=%d,write: %s\n",rc,buf);
    }
    else
    perror("write");
    sleep(10);
    }
    }
    }
    exit(0);
    }



     

  • 相关阅读:
    菜鸡的Java笔记 第二十八
    菜鸡的Java笔记 第二十七
    菜鸡的Java笔记 第二十六
    菜鸡的Java笔记 第二十五 wrapperClass 包装类
    bzoj3238 [Ahoi2013]差异
    bzoj4516 [Sdoi2016]生成魔咒
    bzoj3998 [TJOI2015]弦论
    bzoj1965 [Ahoi2005]洗牌
    bzoj4896 [Thu Summer Camp2016]补退选
    bzoj5055 膜法师
  • 原文地址:https://www.cnblogs.com/wblyuyang/p/2255401.html
Copyright © 2011-2022 走看看