非阻塞IO

我们怎么实现非阻塞io

函数fcntl

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

传入的cmd的值不同, 后面追加的参数也不相同.
fcntl函数有5种功能:
复制一个现有的描述符(cmd=F_DUPFD).
获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW

实现函数SetNoBlock

void SetNoBlock(int fd) { 
	 int fl = fcntl(fd, F_GETFL); 
	 if (fl < 0) { 
		 perror("fcntl");
		 return; 
	 }
	 fcntl(fd, F_SETFL, fl | O_NONBLOCK); 
	}

具体得代码 makefile

testNonBlock: main.cc
	g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
	rm -rf testNonBlock

util.hpp

#pragma once
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <cstring>
#include <cerrno>

void setNonBlock(int fd)
{
    std::cout<<111<<std::endl;
    int f1 = fcntl(fd, F_GETFL);
    if (f1 < 0)
    {
        std::cout << "fcntl" << errno << strerror(errno) << std::endl;
    }
    fcntl(fd, F_SETFL, f1 | O_NONBLOCK);
}

void printLog()
{
    std::cout << "this is a log" << std::endl;
}

void download()
{
    std::cout << "this is a download" << std::endl;
}

void executeSql()
{
    std::cout << "this is a executeSql" << std::endl;
}

main.cc

#include "util.hpp"
#include <cstdio>
#include <vector>
#include <functional>
#include <sys/select.h>
using namespace std;
using func_t = function<void()>;

void init(vector<func_t> &cbs)
{
    cbs.push_back(printLog);
    cbs.push_back(download);
    cbs.push_back(executeSql);
}

void doWork(const vector<func_t> &cbs)
{
    for (auto const &cb : cbs)
    {
        cb();
    }
}

int main()
{
    vector<func_t> cbs;
    init(cbs);
    setNonBlock(0);
    char buffer[1024];
    while (true)
    {
        // printf(">>> ");
        // fflush(stdout);

        ssize_t n = read(0, buffer, sizeof(buffer) - 1);
        if (n > 0)
        {
            // 我们在终端输入得时候输入为 111\n 若我们buffer[n]=0 结果 111\n\0 会多输出一个空格
            buffer[n - 1] = 0;
            cout << "echo# " << buffer << std::endl;
        }
        else if (n == 0)
        {
            cout << "read end" << endl;
            break;
        }
        else
        {   // -1
        //     11Resource temporarily unavailable
            // cout << n << endl;
            // cout << errno << strerror(errno) << endl;

            if(errno==EAGAIN)
            {
                cout<<"我没错 ,我只是没有数据"<<endl;
                doWork(cbs);
            }
            else if(errno==EINTR)
            {
                continue;
            }
            else
            {
                std::cout << "n : " << n << " errno: " << strerror(errno) << std::endl;
                break;
            }

        }
        sleep(1);
    }
    return 0;
}

我们先要知道这里是怎么运行得 ,当我们不输入得时候 ,会执行else得分支。
这里得n =-1 errno=11 Resource temporarily unavailable
这里单纯得n=-1不能辨别非阻塞式IO 。要通过对错误码得观察。
这里得错误码为11 Resource temporarily unavailable 资源未到达在这里并不是一种错误,这时候我们就需要对这个错误码进判别 ,可以去做其他得任务。这里假设我们 得任务很长 ,我们还能及时得响应吗?我验证一下。

执行完一个得时候,我们sleep 3 秒

void doWork(const vector<func_t> &cbs)
{
    for (auto const &cb : cbs)
    {
        cb();
        sleep(3);
    }
}

结果:是能马上处理的(太厉害了)

[zk@VM-24-17-centos lesson42]$ ./testNonBlock 
111
我没错 ,我只是没有数据
this is a log
this is a download
this is a executeSql
asdasd
echo# asdasd
我没错 ,我只是没有数据
this is a log
this is a download

这里还有一个

 else if(errno==EINTR)
            {
                continue;
            }```
这种被系统中断也不是异常得

相关推荐

  1. 阻塞IO

    2024-06-07 03:48:02       9 阅读
  2. 高级IO——阻塞IO和select

    2024-06-07 03:48:02       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-07 03:48:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-07 03:48:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-07 03:48:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-07 03:48:02       20 阅读

热门阅读

  1. tcpdump

    2024-06-07 03:48:02       9 阅读
  2. VOJ 迷阵突围 题解 次短路径 dijkstra算法

    2024-06-07 03:48:02       9 阅读
  3. Kotlin 重写与重载

    2024-06-07 03:48:02       11 阅读
  4. LiveData是如何感知Room数据变化的

    2024-06-07 03:48:02       11 阅读
  5. JVM类加载时机

    2024-06-07 03:48:02       9 阅读
  6. Dart中with的用法

    2024-06-07 03:48:02       9 阅读
  7. Kotlin 内联值类(@JvmInline value class)

    2024-06-07 03:48:02       10 阅读
  8. 【WP|7】深入解析WP_Query

    2024-06-07 03:48:02       10 阅读