1. 阻塞和非阻塞 IO
-
阻塞 IO:会等待操作的完成或期待事情的到来。会被信号打断(信号会打断阻塞中的系统调用),若被打断则错误码为 EINTR(假错)。操作的完成和期待事件的到来会通知阻塞的进程。
-
非阻塞 IO:若操作未完成或期待的事情还没到来,则立即返回,不会等待。若未发生期待事件则返回错误码 EAGAIN(假错)。不会通知,但可以通过轮询查看状态。
1-io/advio/nonblock/relayer
2. IO 多路转接(select、poll、epoll)
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
// 删除指定的fd
void FD_CLR(int fd, fd_set *set);
// 判断fd是否在集合中
int FD_ISSET(int fd, fd_set *set);
// 将fd加入到集合中
void FD_SET(int fd, fd_set *set);
// 清空集合
void FD_ZERO(fd_set *set);
-
监视内容和监视结果存放在同一处 readfds、writefds、exceptfds。
-
文件描述符有大小限制。
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
#include <sys/epoll.h>
// 打开一个epoll文件描述符
int epoll_create(int size);
int epoll_create1(int flags);
// 控制epoll文件描述符
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// 等待epoll文件描述符上的事件
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *sigmask);
3. 存储映射 IO(mmap)
#include <sys/uio.h>
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
-
addr: 指定映射的虚拟内存地址,若为 NULL 则由内核选择合适的虚拟内存地址;
-
length:映射的长度;
-
prot:映射内存的保护模式,可选值如下:
-
flags:指定映射的类型,可选值如下:
-
fd:进行映射的文件描述符;
-
offset:文件偏移量(从文件何处开始映射);
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stderr, "Usage..\n");
exit(1);
}
int fd;
void *addr;
char *p;
struct stat statbuf;
int anum = 0;
if ((fd = open(argv[1], O_RDONLY)) < 0)
{
perror("open");
exit(1);
}
if (fstat(fd, &statbuf) < 0)
{
perror("fstat");
exit(1);
}
addr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED)
{
perror("mmap()");
exit(1);
}
p = (char *)addr;
for (int i = 0; i < statbuf.st_size; i++)
{
if (*(p + i) == 'a')
{
anum++;
}
}
munmap(addr, statbuf.st_size);
printf("the number of a in the file is: %d\n", anum);
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define MEMSIZE 1024
int main()
{
int fd;
pid_t pid;
char *addr;
addr = (char *)mmap(NULL, MEMSIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED)
{
perror("mmap");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if (pid == 0) // child
{
strcpy(addr, "Hello!");
munmap(addr, MEMSIZE);
exit(0);
}
else // parent
{
wait(NULL);
puts(addr);
munmap(addr, MEMSIZE);
exit(0);
}
}
4. 文件锁(fcntl、lockf、flock)
#include <unistd.h>
int lockf(int fd, int cmd, off_t len);
#include <sys/file.h>
int flock(int fd, int operation);
评论(0)
您还未登录,请登录后发表或查看评论