非阻塞I/O
调用 fcntl() 设置文件描述符 O_NONBLOCK 标志,调用 read() 和 write() 不再阻塞,有可能会返回 -1 并设置 errno 为 EAGAIN。
记录锁(字节锁)
用于锁住文件的某一部分,支持读锁和写锁。由于锁信息 lockf_entry 和 v-node 对应,系统并不关心也不知道锁和文件描述符的对应关系。如果同一个进程有多个文件描述符(包括 dup() 和 open())指向同一个文件,对任意一个 close() 都会导致全部解锁。如果在文件尾部加锁,文件向后增长时,新增内容也加了锁。fork() 子进程不继承父进程的锁。
建议性锁:由程序员主动检测锁,有锁时主动保证不进行I/O操作;
强制性锁:不管有没有锁,直接进行I/O,由内核保证锁起作用。
struct flock { short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ short int l_whence; /* Where `l_start‘ is relative to (like `lseek‘). */ __off_t l_start; /* Offset where the lock begins. */ __off_t l_len; /* Size of the locked area; zero means until EOF. */ __pid_t l_pid; /* Process holding the lock. */ }; fcntl(fd, F_SETLK or F_SETLKW or F_GETLK, & fl);
I/O多路转接(I/O多路复用)
主要是用于同时等待多个I/O。阻塞在等待函数 select()、poll() 上,而非特定文件描述符上。select() 和 poll() 不重启。
/* Check the first NFDS descriptors each in READFDS (if not NULL) for read readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out after waiting the interval specified therein. Returns the number of ready descriptors, or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ // nfds 是 readfds、writefds、exceptfds 里最大的描述符序号 +1,可可以是 FD_SETSIZE // timeout 用来设置超时,NULL 为永远阻塞 // 返回 -1 表示出错,如产生信号;其它表示准备好的描述符数量 // readfds、writefds、exceptfds 在返回后保存的是准备好的描述符 extern int select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout); #define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) #define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) #define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) #define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) // 调用时屏蔽 sigmask 里的信号 extern int pselect (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, const struct timespec *__restrict __timeout, const __sigset_t *__restrict __sigmask);
#define POLLIN 0x001 /* There is data to read. */ #define POLLPRI 0x002 /* There is urgent data to read. */ #define POLLOUT 0x004 /* Writing now will not block. */ /* Data structure describing a polling request. */ struct pollfd { int fd; /* File descriptor to poll. */ short int events; /* Types of events poller cares about. */ short int revents; /* Types of events that actually occurred. */ }; int poll (struct pollfd *__fds, nfds_t __nfds /* fds 的数量 */, int __timeout /* -1 为永远阻塞,其它为毫秒数 */);
时间: 2024-10-04 22:05:53