一.记录锁 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。 |
|
来自: 书永夜 > 《Linux系统编程》