1.非阻塞IO
对于一个给定的描述符有两种方法对其指定非阻塞IO
1)如果调用open获得描述符,则可指定O_NONBLOCK标志
2)对于一个已经打开的描述符,则可调用fcntl由该函数打开O_NONBLOCK文件状态标志
#include "apue.h" #include <errno.h> #include <fcntl.h> char buf[500000]; int main(void) { int ntowrite, nwrite; char *ptr; ntowrite = read(STDIN_FILENO, buf, sizeof(buf)); fprintf(stderr, "read %d bytes\n", ntowrite); set_fl(STDOUT_FILENO, O_NONBLOCK); /* set nonblocking */ ptr = buf; while (ntowrite > 0) { errno = 0; nwrite = write(STDOUT_FILENO, ptr, ntowrite); fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno); if (nwrite > 0) { ptr += nwrite; ntowrite -= nwrite; } } clr_fl(STDOUT_FILENO, O_NONBLOCK); /* clear nonblocking */ exit(0); }
2. 记录锁
记录锁锁定文件中的一个区域
#include <fcntl.h> int fcntl(int filedes, int cmd, ... /* struct flock *flockptr */ );
扫描二维码关注公众号,回复:
1348627 查看本文章
|
Returns: depends on cmd if OK (see following), 1 on error |
cmd is F_GETLK, F_SETLK, or F_SETLKW
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
off_t l_start; /* offset in bytes, relative to l_whence */
short l_whence; /* SEEK_SET, SEEK_CUR, or SEEK_END */
off_t l_len; /* length, in bytes; 0 means lock to EOF */
pid_t l_pid; /* returned with F_GETLK */
};
例:加锁和解锁一个文件区域的函数
#include "apue.h" #include <fcntl.h> int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) { struct flock lock; lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */ lock.l_start = offset; /* byte offset, relative to l_whence */ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock.l_len = len; /* #bytes (0 means to EOF) */ return(fcntl(fd, cmd, &lock)); }
锁的隐含继承和释放
1)
2)
3)
4)
建议性锁和强制性锁
3.STREAMS
1)putmsg和putpmsg函数
2)ioctl
3)写至流
4)写模式
5)getmsg和getpmsg函数
6)读模式
4.IO多路转接
#include <sys/select.h>
int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr); |
Returns: count of ready descriptors, 0 on timeout, 1 on error |
#include <sys/select.h> int pselect(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, const struct timespec *restrict tsptr, const sigset_t *restrict sigmask); |
Returns: count of ready descriptors, 0 on timeout, 1 on error |
#include <poll.h> int poll(struct pollfd fdarray[], nfds_t nfds, int timeout); |
Returns: count of ready descriptors, 0 on timeout, 1 on error |
5.异步IO
6.readv和writev函数
7.readn和writen函数
8存储映射IO
#include <sys/mman.h> void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off ); |
Returns: starting address of mapped region if OK, MAP_FAILED on error |
例:用存储映射IO复制文件
#include "apue.h" #include <fcntl.h> #include <sys/mman.h> int main(int argc, char *argv[]) { int fdin, fdout; void *src, *dst; struct stat statbuf; if (argc != 3) err_quit("usage: %s <fromfile> <tofile>", argv[0]); if ((fdin = open(argv[1], O_RDONLY)) < 0) err_sys("can't open %s for reading", argv[1]); if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE)) < 0) err_sys("can't creat %s for writing", argv[2]); if (fstat(fdin, &statbuf) < 0) /* need size of input file */ err_sys("fstat error"); /* set size of output file */ if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) err_sys("lseek error"); if (write(fdout, "", 1) != 1) err_sys("write error"); if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED) err_sys("mmap error for input"); if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == MAP_FAILED) err_sys("mmap error for output"); memcpy(dst, src, statbuf.st_size); /* does the file copy */ exit(0); }