Linux系统调用与文件IO(二)

    xiaoxiao2025-10-15  4

    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); }
    转载请注明原文地址: https://ju.6miu.com/read-1303179.html
    最新回复(0)