例:同時讀取鼠標與鍵盤異步
傳統狀況下,因爲阻塞只能同時讀取一路。函數
解決方案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)處理大文件時效率高,小文件不划算