I/O複用-select函數

以前咱們使用了幾種服務器模型,一個是單進程的, 同一時候只能給一個客戶端提供服務, 後來咱們使用了多進程, 每一個客戶端fork新進程進行業務處理bash

IO多路複用是指內核一旦發現進程指定的一個或者多個IO條件準備讀取,它就通知該進程,能夠使用一個進程服務多個客戶端.服務器

多進程服務模型:

I/O 複用進程模型:

select 實現I/O 複用

select函數原型:函數

#include <sys/select.h>
#include <sys/time.h>

int select(int maxfd, fd_set * readset, fd_set * writeset, fd_set * exceptset, const struct timeval * timeout);

成功時返回大於0的值, 失敗時返回 -1
複製代碼

參數解釋:ui

maxfd 監視對象文件描述符的數量,舉例寫法 sever_sock+1
readset 存儲的待讀取數據文件描述符
writeset 可傳輸無阻塞數據文件描述符 
exceptset 發生異常的文件描述符
timeout 超時設置
複製代碼

select函數返回值, 若是返回大於0的整數, 說明相應數量的文件描述符發生了變化.spa

文件描述符管理

咱們發如今 參數類型上有 fd_set類型,這是什麼類型呢? 咱們設置的文件描述符對應的位存儲數據格式, 咱們設置這些文件描述符對應位時, 能夠使用一些宏實現3d

FD_ZERO(fd_set * fdset) 
將 fd_set 變量的全部位初始化位0

FD_SET(int fd, fd_set * fdset)
在參數 fd_set 指向的變量中註冊文件描述符 fd 的信息

FD_CLR(int fd, fd_set * fdset)
從參數 fdset 指向的變量中清除文件描述符 fd 的信息

FD_ISSET(int fd, fd_set * fdset) 
若參數 fdset  指向的變量中包含文件描述符 fd 的信息,則返回真
複製代碼

timeval 超時設置結構體

struct timeval 
{
    long tv_sec;  //seconds
    long tv_usec; //microseconds
}
複製代碼

示例圖

示例代碼(回聲)

select.ccode

#include <stdio.h>
#include <sys/select.h>

#define BUF_SIZE 1024

int main(int argc, char *argv[])
{
    //監視的文件描述符
    fd_set reads, temps;
    struct timeval timeout;
    int result, str_len;
    char buf[BUF_SIZE];

    FD_ZERO(&reads);
    FD_SET(0, &reads); //0 is standard input(console)

    while (1)
    {
        //由於每次select會重置監控句柄,因此賦值給臨時
        temps = reads;

        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        // puts 只有事件發生或者發生超時才執行,不然select阻塞
        puts("xxxx");
        result = select(1, &temps, 0, 0, &timeout);

        if (result == -1)
        {
            puts("select() error");
        }
        else if (result == 0)
        {
            puts("nothing event change..time out");
        }
        else
        {
            if (FD_ISSET(0, &temps))
            {
                str_len = read(0, buf, BUF_SIZE);
                printf("message from consle: %s\n", buf);
            }
        }
    }
}
複製代碼
gcc select.c -o select

./select
xxxx
123456
message from consle: 123456

xxxx
7890ha
message from consle: 7890ha

xxxx
nothing event change..time out
xxxx
777
message from consle: 777

xxxx
^C
複製代碼
相關文章
相關標籤/搜索