高級IO

 

 

例:同時讀取鼠標與鍵盤異步

傳統狀況下,因爲阻塞只能同時讀取一路。函數

解決方案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)處理大文件時效率高,小文件不划算

相關文章
相關標籤/搜索