例:同时读取鼠标与键盘异步
传统状况下,因为阻塞只能同时读取一路。函数
解决方案spa
1.非阻塞IOcode
2.异步IOblog
3.IO多路复用进程
非阻塞IO事件
使用O_NONBLOCK和fcntl实现非阻塞内存
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { int fd = -1; int flag = -1; int ret = -1; //把0号文件描述符(stdin)变为非阻塞 flag = fcntl(0,F_GETFL); flag |= O_NONBLOCK; fcntl(0, F_SETFL, flag);//设置为非阻塞 fd = open("/dev/input/mouse1", O_RDONLY|O_NONBLOCK); if(fd < 0) { perror("open"); exit(-1); } char buf[100]; //读鼠标 while(1) { memset(buf , 0, sizeof(buf)); ret = read(fd , buf , 100); if(ret > 0) { printf("鼠标读取的内容:[%s]\n" , buf); } memset(buf , 0, sizeof(buf)); ret = read(0 , buf , 100); if(ret > 0) { printf("键盘读取的内容:[%s]\n" , buf); } } return 0; }
异步IOget
使用select和poll实现异步IOinput
特色为外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <poll.h> int main(void) { // 读取鼠标 int fd = -1, ret = -1; char buf[200]; struct pollfd myfds[2] = {0}; fd = open("/dev/input/mouse1", O_RDONLY); if (fd < 0) { perror("open:"); return -1; } // 初始化咱们的pollfd myfds[0].fd = 0; // 键盘 myfds[0].events = POLLIN; // 等待读操做 myfds[1].fd = fd; // 鼠标 myfds[1].events = POLLIN; // 等待读操做 ret = poll(myfds, fd+1, 10000); if (ret < 0) { perror("poll: "); return -1; } else if (ret == 0) { printf("超时了\n"); } else { // 等到了一路IO,而后去监测究竟是哪一个IO到了,处理之 if (myfds[0].events == myfds[0].revents) { // 这里处理键盘 memset(buf, 0, sizeof(buf)); read(0, buf, 5); printf("键盘读出的内容是:[%s].\n", buf); } if (myfds[1].events == myfds[1].revents) { // 这里处理鼠标 memset(buf, 0, sizeof(buf)); read(fd, buf, 50); printf("鼠标读出的内容是:[%s].\n", buf); } } return 0; }
异步IO
经过信号实现
异步IO的工做方法是:咱们当前进程注册一个异步IO事件(使用signal注册一个信号SIGIO的处理函数),而后当前进程能够正常处理本身的事情,当异步事件发生后当前进程会收到一个SIGIO信号从而执行绑定的处理函数去处理这个异步事件。
涉及的函数:
(1)fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN)
(2)signal或者sigaction(SIGIO)
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h>
int mousefd = -1;
// 绑定到SIGIO信号,在函数内处理异步通知事件 void func(int sig) { char buf[200] = {0}; if (sig != SIGIO) return; read(mousefd, buf, 50); printf("鼠标读出的内容是:[%s].\n", buf); } int main(void) { // 读取鼠标 char buf[200]; int flag = -1; mousefd = open("/dev/input/mouse1", O_RDONLY); if (mousefd < 0) { perror("open:"); return -1; } // 把鼠标的文件描述符设置为能够接受异步IO flag = fcntl(mousefd, F_GETFL); flag |= O_ASYNC; fcntl(mousefd, F_SETFL, flag); // 把异步IO事件的接收进程设置为当前进程 fcntl(mousefd, F_SETOWN, getpid()); // 注册当前进程的SIGIO信号捕获函数 signal(SIGIO, func); // 读键盘 while (1) { memset(buf, 0, sizeof(buf)); //printf("before 键盘 read.\n"); read(0, buf, 5); printf("键盘读出的内容是:[%s].\n", buf); } return 0; }
存储映射IO
一、mmap函数二、LCD显示和IPC之共享内存三、存储映射IO的特色(1)共享而不是复制,减小内存操做(2)处理大文件时效率高,小文件不划算