linux操作系统基础知识

用户空间和内核空间

操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。

对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G)。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。

文件描述符

File descriptor用于表述只想文件的引用的抽象概念。文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

进程阻塞

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。

可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。当进程进入阻塞状态,是不占用CPU资源的。

进程切换

为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:

1. 保存处理机上下文,包括程序计数器和其他寄存器。

上下文就是内核再次唤醒当前进程时所需要的状态,由一些对象(程序计数器、状态寄存器、用户栈等各种内核数据结构)的值组成。

这些值包括描绘地址空间的页表、包含进程相关信息的进程表、文件表等。

2. 更新PCB信息。

3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。

4. 选择另一个进程执行,并更新其PCB。

5. 更新内存管理的数据结构。

6. 恢复处理机上下文。

总而言之就是很耗资源,具体的可以参考这篇文章:进程切换

直接IO和缓存IO

缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。

以write为例,数据会先被拷贝进程缓冲区,在拷贝到操作系统内核的缓冲区中,然后才会写到存储设备中。

直接I/O的write:(少了拷贝到进程缓冲区这一步)

缓存 I/O 的缺点:

数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。

IO 模式

对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说,当一个read操作发生时,它会经历两个阶段:

1. 等待数据准备 (Waiting for the data to be ready)

2. 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)

正式因为这两个阶段,linux系统产生了下面五种网络模式的方案。

- 阻塞 I/O(blocking IO)

- 非阻塞 I/O(nonblocking IO)

- I/O 多路复用( IO multiplexing)

- 信号驱动 I/O( signal driven IO)实际中并不常用

- 异步 I/O(asynchronous IO)

阻塞IO

在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:

read为例:

进程发起read,进行recvfrom系统调用;

内核开始第一阶段,准备数据(从磁盘拷贝到内核缓冲区),进程请求的数据并不是一下就能准备好;准备数据是要消耗时间的;

在这个过程中,整个用户进程将会被阻塞(进程自己选择的阻塞),等待数据;

直到数据从内核拷贝到了用户空间,内核返回结果,进程解除阻塞,重新运行起来。

因此,内核准备数据和数据从内核拷贝到进程内存地址这两个过程都是阻塞的。

非阻塞IO模型

可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:

当用户进程发出read操作时,如果kernel中的数据还没有准备好;

那么它并不会block用户进程,而是立刻返回一个error,从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果;

用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call;

那么它马上就将数据拷贝到了用户内存,然后返回。

所以,nonblocking IO的特点是用户进程在内核准备数据的阶段需要不断的主动询问数据好了没有。

IO多路复用

I/O多路复用使用select, poll, epoll监听多个io对象,当io对象有变化(有数据)的时候就通知用户进程。好处就是单个进程可以处理多个socket。当然具体区别我们后面再讨论,现在先来看下I/O多路复用的流程:

当用户进程调用了select,那么整个进程会被block;

而同时,kernel会“监视”所有select负责的socket;

当任何一个socket中的数据准备好了,select就会返回;

这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。

所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

和阻塞IO相比,这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个connection。

所以,如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用多线程 + 阻塞 IO的web server性能更好,可能延迟还更大。

select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。

异步 IO

用户进程发起read操作之后,立刻就可以开始去做其它的事。

而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。

然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

小结

在non-blocking IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的check,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。

而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。

python 异步io_python之同步IO和异步IO相关推荐

  1. 【OkHttp】OkHttp Get 和 Post 请求 ( 同步 Get 请求 | 异步 Get 请求 | 同步 Post 请求 | 异步 Post 请求 )

    OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...

  2. 关于“异步复位,同步复位,异步复位同步释放”的理解

    文章目录 1. 异步复位 2. 同步复位 3. 异步复位同步释放 今天好好理一理异步复位,同步复位,以及亚稳态中的异步复位同步释放. 1. 异步复位 一般让复位信号低电平有效 复位信号不受时钟的控制, ...

  3. java同步接口和异步接口_同步接口和异步接口

    定义 答案:来自网络搜索 同步调用:当一个支付请求被发送到支付渠道方,支付渠道会很快返回一个结果.但是这个结果,只是告诉你调用成功了,不是扣款成功,这叫同步调用; 异步调用:同步请求参数里面会有一个回 ...

  4. java同步异步区别_同步请求和异步请求的区别

    同步请求和异步请求的区别 先解释一下同步和异步的概念 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式. 异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的 ...

  5. php和ajax的同步和异步请求,ajax 同步请求和异步请求的差异分析_javascript技巧

    ajax同步和异步的差异, 先看2段代码: 代码一: Synchronize = function(url,param) { function createXhrObject() { var http ...

  6. python磁盘io_Python多线程同步、互斥锁、死锁

    接着上篇多线程继续讲,上篇最后的多线程共享全局变量对变量的处理值出错在本文中给出解决方案. 出现这个情况的原因是在python解释器中GIL全局解释器锁. GIL:全局解释器锁,每个线程在执行的过程都 ...

  7. Mysql主从复制之异步与半同步以及主从切换(实验)

    什么是异步,半同步: 一.异步复制(Asynchronous replication) 1.逻辑上 MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库 ...

  8. 异步协议与同步协议:面向字符的协议BSC协议

    在数据通信中,协议是用来实现OSI模型中一层或几层的一组规则或规范. 数据链路层协议是实现数据链路层的一组规范. 数据链路协议可以被分为两组:异步协议和同步协议.异步协 议对于比特流中的每个字符都单独 ...

  9. ajax同步请求和异步请求的区别

    刚毕业那会有一位面试官问我的问题,现在想做个总结 jquery 的 async 这个属性 默认是true:异步 , false:同步. 那么异步和同步到底有什么区别呢? 异步:异步处理是客户端通过事件 ...

最新文章

  1. 【学习笔记】超简单的快速数论变换(NTT)(FFT的优化)(含全套证明)
  2. 12.6日个人工作总结
  3. 404错误处理以及以后缀为action结尾的处理
  4. 1.2.3 TCP/PI参考模型(应用层、传输层、网际层、网络接口层)、五层参考模型(应用层、传输层、网络层、数据链路层、物理层)、OSI与TCP/IP参考模型比较
  5. boost::sort模块float_sort 右移函子排序示例
  6. centons7网卡配置文件使用openvswitch bridge
  7. DropDownList的项按字母顺序排列
  8. win10如何截屏_6个Win10系统使用小技巧,对你一定有用!
  9. AD18学习速通教程
  10. itextpdf使用总结
  11. 3D建模师是吃青春饭的吗?被高薪挖掘的建模人才,靠的是这个
  12. 验证码接码短信平台 - 小程序版
  13. 2021年,这个岗位发展前景广,刚入行月薪上万?
  14. python none什么意思_python – 什么是self = None?
  15. 104 polkadot substrate : 许可网络
  16. Cent OS 7扩容
  17. 【C语言】题集 of ②
  18. 亚马逊ec2 删除实例_学习使用Amazon EC2实例部署php应用程序
  19. arduino 温度调节器_怎样使用Arduino制作自己的温度控制器
  20. Allegro Design Entry HDL(OrCAD Capture HDL)软件界面详细介绍

热门文章

  1. 吞吐量达到瓶颈后下降_中港协:八大枢纽港集装箱吞吐量增速创新高
  2. pwntools解题脚本模板
  3. python列表list的基本性质
  4. python基础教程:排列与组合
  5. python3 基础教程: 文件read方法(read、readline、readlines)
  6. Python中的测试工具
  7. Python:判定IP地址合法性的三种方法
  8. 视频编码中的RC(rate control)是什么?码率控制 CBR (Constant Bit Rate)、VBR (Variable Bit Rate)
  9. Intel Realsense 如何获取已连接所有摄像头的序列号参数?context() query_devices() size() camera_info device_list
  10. 跟着书本学习CSS(2)