linux---五种高级IO模型

2023-05-16

  • 阻塞IO模型
  • 非阻塞IO模型
  • 信号驱动IO模型
  • 异步IO模型
  • 多路转接IO模型
  • 高级IO重要概念
  1. 阻塞IO模型

在内核将数据准备好,系统调用会一直等待,所有的套接字默认都是阻塞IO方式
阻塞IO是最常见的IO模型
在这里插入图片描述

  1. 非阻塞IO模型

非阻塞IO往往需要程序员循环的方式反复尝试读取文件描述符,这个过程称为轮询,这对于cpu来说的话是较大的浪费,一般只有特定的场景下才能使用
在这里插入图片描述

  1. 信号驱动IO模型

内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作
在这里插入图片描述

  1. 异步IO

由内核在数据拷贝完成的时候,通知应用程序(而信号驱动是高数应用程序什么时候进行数据拷贝)
在这里插入图片描述

  1. IO多路转接

IO多路转接看起来和阻塞IO类似,实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态

在这里插入图片描述

  1. 高级IO概念
    1)同步与异步
  • 所谓的同步,就是在发出一个调用时候,在没有得到结果之前,该调用就不返回,但是一旦调用返回就得到返回值;换句话说,就是有调用栈主动等待这个调用的结果

  • 异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果,换句话说就是当一个异步过程调用发出之后,调用者不会立刻得到结果,而是在调用发出之后,被调用者通过状态,通知调用者,或者通过回调函数处理这个调用

  • 两者之间的区别:功能是不是自己来完成

    2)阻塞和非阻塞

    • 阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会被返回
    • 非阻塞调用是指在不能立刻得到结果之前,该调用不会阻塞当前线程。
    • 两者之间的区别:调用函数的时候条件不满足的时候是否会停止该线程的运行。

将一个文件描述符设置成非阻塞IO
一个文件描述符默认都是阻塞IO,可以使用fcntl()函数设置成阻塞IO。

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

根据我们传递的cmd的值不同,后面的参数也不相同
fcntl函数有五种功能

  • 赋值一个现有的文件描述符(cmd=F_DUPFD)
  • 获得/设置文件描述符标记(cmd=F_GETFD或者F_SETFD)
  • 获得/设置一个文件状态标记(cmd=F_GETFL或者F_SETFL)
  • 获得/设置异步IO所有权(cmd=F_GETOWN或者F_SETOWN)
  • 或者/设置记录锁(cmd=F_GETLK或者F_SETLKW)

将一个文件描述符设置成非阻塞只需要三行代码

int f1 = fcntl(fd,F_GETFL);
f1 = f1 | O_NONBLOCK;
fcntl(fd,F_SETFL,f1);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux---五种高级IO模型 的相关文章

  • Python 在打开套接字时可以选择哪个网络适配器吗?

    运行 python 应用程序的目标计算机将具有三个可用的网络接口 一般来说 所有三个网络都会有很大不同 但是三个网络中的两个可能位于相似的网络上 在下面的示例中 我无法控制 ETH 2 上的目标地址 因为它是预先配置的系统 因此我被迫以编程
  • 如果执行 shell 失败,jenkins 构建不会失败

    作为构建过程的一部分 我运行 git commit 作为执行 shell 步骤 但是 如果工作区中没有任何更改 Jenkins 将导致构建失败 这是因为当没有要提交的更改时 git 返回错误代码 如果是这种情况 我想要么中止构建 要么将其标
  • 如何在 ssh 命令中使用长输入参数正确转义 qsub 命令?

    我有一个复杂的 qsub 命令可以远程运行 PROJECT NAME TEXT TEST PROJECT PACK ORGANIZATION source organization MY ORGANIZATION CONTACT NAME
  • Linux 上的 头文件在哪里?为什么我找不到 ? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在Linux中实现C的getch 函数 https stackoverflow com questions 3276546 how to implement getch function of c
  • 如何编写写入 /var/log/myapp 目录的 C/C++ 应用程序?

    背景 在 Linux 系统上 应用程序日志 https help ubuntu com community LinuxLogFiles Application Logs存在于子目录中 var log 其所有者为root root并且在我的系
  • php.ini 更改,但在 Ubuntu 上无效

    我想更改 PHP 上传文件大小的限制 这是我的输出的一些信息phpinfo https www php net manual en function phpinfo php Configuration File php ini Path e
  • 如何在 Linux 中检测通过 GUI 登录的用户

    我想在我的程序中捕获通过 GUI 登录的用户名 我的程序作为守护进程从 root 登录运行 如果非 root 用户通过 GUI 登录 我的程序应该会收到通知 我正在粘贴我当前的程序 该程序调用一个 perl 脚本 利用系统调用来检查当前登录
  • 哪个信号被传递到信号处理程序中死锁的进程

    我有一个来自调用信号处理程序后死锁的进程的核心转储 如何确定传送了哪个信号以及是谁发送的 GDB 为接收信号的线程生成的回溯如下 信号处理程序在第 15 帧中被调用 gdb bt 0 0x00007fa9c204654b in sys fu
  • 您可以bind()和connect() UDP连接的两端吗

    我正在编写一个点对点消息队列系统 它必须能够通过 UDP 运行 我可以任意选择一侧或另一侧作为 服务器 但这似乎不太正确 因为两端都从另一端发送和接收相同类型的数据 是否可以绑定 和连接 两端 以便它们只能彼此发送 接收 这似乎是一种非常对
  • PHP exec - 检查是否启用或禁用

    有没有办法检查 php 脚本是否exec 在服务器上启用还是禁用 这将检查该功能是否确实有效 权限 权利等 if exec echo EXEC EXEC echo exec works
  • 健全性检查 SSH 公钥? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我已要求用户提供他们的公共 id rsa pub ssh 密钥 然后将其放入 home theiraccount ssh authorized key
  • 启动jetty服务器时出现NoClassDefFoundError

    我正在尝试在码头服务器中托管我的网络应用程序 spring 我将 war 文件复制到 jetty 服务器中的 webapp 文件夹中 我并不是想嵌入jetty服务器 而是试图在jetty内托管应用程序 如tomcat 我没有安装jetty
  • Bash 变量:区分大小写?

    Bash shell 脚本区分大小写吗 是可变的date与DATE 是的 它区分大小写 就像 UNIX 的其余部分一样 date and DATE是两个不同的变量 makefile and Makefile是两个不同的文件 h and H是
  • Linux 缓冲区溢出环境变量

    我一直在审查不同类型的缓冲区溢出 并遇到了一个我不记得为什么会发生的问题 下面的代码是我尝试执行缓冲区溢出的程序 include
  • /etc/php5/conf.d 文件夹中的 .ini 文件有什么用?

    我知道 ini 文件位于 etc php5 cli与 PHP 的 CLI 使用有关 文件位于 etc php5 fpm是关于 PHP 的 FastCGI FPM 方面 但是位于以下位置的 ini 文件又如何呢 etc php5 conf d
  • 获取当前时间(以小时和分钟为单位)

    我正在尝试从系统收集信息 并且需要获取当前时间 以小时和分钟为单位 目前我有 date awk print 4 输出如下 16 18 54 怎样才能把秒数去掉呢 提供格式字符串 date H M Running man date将给出所有格
  • 如何永久清除 linux/ubuntu 终端或 bash 中的所有历史记录? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 当您在 Linux 终端中使用向上键时 可以再次使用之前的命令 很棒的功能 但是 我开始使用命令中的敏感详细信息将 mysql 记录到 mysql 中
  • 从命令输出中设置 GDB 中的环境变量

    我试图在挑战中利用缓冲区溢出 缓冲区从环境变量中获取其值 在 GDB 中 我知道您可以使用以下命令设置环境变量 set environment username test 但是我需要传递用户名变量特殊字符 所以我需要执行以下操作 set e
  • 保护一个保存 MySQL 数据库的简单 Linux 服务器?

    这是一个初学者问题 但我浏览了该网站上的许多问题 但没有找到简单直接的答案 我正在设置一个运行 Ubuntu 的 Linux 服务器来存储 MySQL 数据库 该服务器尽可能安全非常重要 据我所知 我主要担心的是传入的 DoS DDoS 攻
  • 无法使用Linux服务启动Archiva 2.1.0

    我正在尝试在 Linux 上启动最近发布的 Apache Archiva v2 1 0 独立版 出于测试目的 该 zip 已解压缩在 opt archiva 2 0 文档说 http archiva apache org docs 2 1

随机推荐