因为write调用不会等到硬盘IO完成之后才返回,因此如果OS在write调用之后、硬盘同步之前崩溃,则数据可能丢失。...更加高效(因为应用程序通常知道自己的脏页位置),但实际上(Linux)kernel中有着十分高效的数据结构,能够很快地找出文件的脏页,使得fsync只会同步文件的修改内容。...类似,但是仅仅在必要的情况下才会同步metadata,因此可以减少一次IO写操作。...(实际上,Linux对O_SYNC/O_DSYNC做了相同处理,没有满足Posix的要求,而是都实现了fdatasync的语义)相对于fsync/fdatasync,这样的设置不够灵活,应该很少使用。...使用fdatasync优化日志同步 文章开头时已提到,为了满足事务要求,数据库的日志文件是常常需要同步IO的。由于需要同步等待硬盘IO完成,所以事务的提交操作常常十分耗时,成为性能的瓶颈。
一、模拟普通同步 我们用两个函数来模拟两个客户端请求,并依次进行处理 def...hljs-string">"__main__": main() 执行结果 开始处理请求req_a 完成处理请求req_a 开始处理请求req_b 完成处理请求req_b 说明:同步是按部就班的依次执行...,始终按照同一个步调执行,上一个步骤未执行完不会执行下一步 二、模拟耗时同步 在处理请求req_a时需要执行一个耗时的工作(如IO)其执行过程如下 ...(): """模拟耗时IO操作"""</span...操作 完成IO操作 ret: io result 完成处理请求req_a 开始处理请求req_b 完成处理请求req_b 说明:耗时的操作会将代码执行阻塞住,即req_a未处理完req_b是无法执行的
在 linux 中对 io 操作就是把内核态准备就绪的数据拷贝到用户态。 啥是内核态呢,内核态就是 linux 内核,用户态则是用户进程中的某个线程,即 io 操作其实就是内核态和用户态的切换。...io 操作大致分为两种: 文件 io 网络 io io 操作分为两步 发起 io 请求 接收处理 io 同步 io 和异步 io 最大的区别就是同步 io 的发起方(用户线程)会阻塞或轮询等待 io 完成...同步 io 的特点 1、同步 io 是用户线程发起 io 请求并以阻塞或轮询的方式来等待 io 的完成 2、同步 io 是 io 的发起方,同时也是处理方 3、同步 io 是需要将内核态准备就绪的数据拷贝到用户态...,所以需要阻塞用户态程序并等待 io 完成 异步 io 的特点 1、异步 io 在用户线程发起 io 请求后会立即返回继续执行后续的逻辑流 2、异步 io 是 io 的发起方,但内核态才是处理方 3、异步...总结以上几种 io 模型,除了最后一个是异步 io 模型,其它的 io 模型都是同步。
目的 本片文章主要讲解同步I/O与异步I/O相关知识,希望通过编写本篇文章为起点,对windows内核原理知识进行学习与梳理。发现并弥补遗漏的知识点并加以学习。...使用设备内核对象进行线程同步时,无法区分当前完成通知的I/O是读操作还是写操作,因此无论是读还是写都会将其状态设置为触发状态。...此使我们发出的I/O请求时,系统内核返回IO_PENDDING状态,然后线程就可以继续处理其他事情。...总结 同步I/O会阻塞线程,想要提高执行速度必须增加线程,但是会由于线程上下文切换造成性能损失。 Windows下大约每15ms会进行一次线程调度。...使用异步I/O时线程不会阻塞,系统底层将每个I/O请求生成I/O请求包(IRP)加入到设备驱动程序的请求队列中,然后直接返回IO_PENDDING状态表示请求受理成功,当底层设备完成了真实的I/O请求后会通过中断控制器通过中断操作通知
POSIX 同步IO、异步IO、阻塞IO、非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下。...POSIX(可移植操作系统接口)把同步IO操作定义为导致进程阻塞直到IO完成的操作,反之则是异步IO 按POSIX的描述似乎把同步和阻塞划等号,异步和非阻塞划等号,但是为什么有的人说同步IO不等于阻塞IO...IO模型 这里统一使用Linux下的系统调用recv作为例子,它用于从套接字上接收一个消息,因为是一个系统调用,所以调用时会从用户进程空间切换到内核空间运行一段时间再切换回来。...这一过程就可以看成是使用了阻塞IO模型,因为如果水龙头没有水,他也要等到有水并装满杯子才能离开去做别的事情。很显然,这种IO模型是同步的。 ?...),如果按这样理解,这种IO模型也能称之为非阻塞IO模型,但是按POSIX来看,它也是同步IO,那么也和楼上一样称之为同步非阻塞IO吧。
标准文件访问方式 ---- 直接IO方式 OPEN +O_DIRECT = 绕过内核缓冲区的直接访问,有效避免了CPU和内存的多余时间开销。要求内存边界对齐。...直接IO,绕过缓存,不会出现write成功数据丢失情况。...注意:直接IO的缺点就是如果访问的数据不在应用程序缓存中,那么每次数据都会直接从磁盘进行加载,这种直接加载会非常慢,通常直接IO跟异步IO结合使用会得到较好的性能。...---- O_SYNC 缓存同步 为了保证磁盘系统与缓冲区内容一致,Linux系统提供了sync,fsync,fdatasync三个函数。...而除数据外,fsync还会同步更新文件属性。 ---- Linux文件IO流程图 内核中会有一个线程,不断地将高速页缓冲区中的数据写入到物理磁盘中。
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?...本文讨论的背景是Linux环境下的network IO。...blocking IO 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: ?...所以,blocking IO的特点就是在IO执行的两个阶段都被block了。 non-blocking IO linux下,可以通过设置socket使其变为non-blocking。...只不过process是被select这个函数block,而不是被socket IO给block。 Asynchronous I/O linux下的asynchronous IO其实用得很少。
本文是在《UNIX网络编程 卷1:套接字联网API》6.2节"I/O 模型 "的基础上,即UNIX/LINUX环境下的网络 IO环境下的理解,它里面给出的例子是读取(接收)网络UDP数据。...; 适用高并发服务应用开发:一个进程(线程)响应多个请求; 3、select、poll、epoll Linux中IO复用的实现方式主要有select、poll和epoll: Select:注册IO、阻塞扫描...,Linux2.6后内核支持; 2-4、信号驱动IO模型 ?...3-2、同步IO和异步IO 同步IO:导致请求进程阻塞,直到I/O操作完成。 异步IO:不导致请求进程阻塞。 上面两个定义是《UNIX网络编程 卷1:套接字联网API》给出的。...这里我们的双方是指,用户进程和IO设备;明确同步和异步之后,我们在上面网络输入操作例子的基础上,进行扩展定义: 同步IO:用户进程发出IO调用,去获取IO设备数据,双方的数据要经过内核缓冲区同步,完全准备好后
几个概念 阻塞IO 和非阻塞IO 这两个概念是程序级别的。...同步IO 和 异步IO,这两个概念是操作系统级别的。...同步阻塞模式(Blocking IO) 同步阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操作时如果数据没有准备号会被阻塞。 ?...Java同步阻塞模式编码 多线程客户端 为了测试服务端程序,可以先编写一个多线程客户端用于请求测试。...多线程也无法解决因为 调用底层系统的 同步IO而决定的同步IO机制。 同步阻塞模式总结 BIO模式因为进程的阻塞挂起,不会消耗过多的CPU资源,而且开发难度低,比较适合并发量小的网络应用开发。
本文将结合用户态的接口以及内核态的实现剖析文件IO。...Reference: The Linux Programming Interface: Chapter 4/14/15, Kernel/fs 通用接口 通用IO包含open/read/write/close...文件创建标志 - 创建以及后续IO的选项,不可读写。...因为这个原因,写操作并不能实时的进行持久化,需要linux使用journal机制来保证文件系统的崩溃一致性,然而journal机制本身又需要进行flush。...---- Ioctl 非通用的IO操作,通过指定的request值表示操作,后续传递参数的类型通过request的值进行解释。
四种组合方式 同步阻塞方式: 发送方发送请求之后一直等待响应。 接收方处理请求时进行的IO操作如果不能马上等到返回结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。...同步非阻塞方式: 发送方发送请求之后,一直等待响应。 接受方处理请求时进行的IO操作如果不能马上的得到结果,就立即返回,取做其他事情。...当IO操作完成以后,将完成状态和结果通知接收方,接收方再响应发送方,发送方才进入下一次请求过程。(实际不应用) 异步阻塞方式: 发送方向接收方请求后,不等待响应,可以继续其他工作。...接收方处理请求时进行IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他操作。...接收方处理请求时进行IO操作如果不能马上得到结果,也不等待,而是马上返回去做其他事情。 当IO操作完成以后,将完成状态和结果通知接收方,接收方再响应发送方。
有两种办法: 第一种是CPU等着,也就是程序暂停执行后续代码,等100M的数据在10秒后写入磁盘,再接着往下执行,这种模式称为同步IO; 另一种方法是CPU不等待,只是告诉磁盘,“您老慢慢写,不着急,我接着干别的事去了...同步和异步的区别就在于是否等待IO执行的结果。...好比你去麦当劳点餐,你说“来个汉堡”,服务员告诉你,对不起,汉堡要现做,需要等5分钟,于是你站在收银台前面等了5分钟,拿到汉堡再去逛商场,这是同步IO。...很明显,使用异步IO来编写程序性能会远远高于同步IO,但是异步IO的缺点是编程模型复杂。 想想看,你得知道什么时候通知你“汉堡做好了”,而通知你的方法也各不相同。...总之,异步IO的复杂度远远高于同步IO。 读文件 1、读写一个文件之前需要打开它: fileobj = open(filename, mode) mode :文件类型和操作的字符串。
简单的编程模型:使用 select 可以让开发者避免复杂的多线程或多进程编程,开发者可以在一个单一的事件循环中处理多个连接,而不必担心线程同步和互斥。...fdset 从用户态拷贝到内核态,在高并发下是个巨大的性能开销(可优化为不拷贝); 调用 select 阻塞后,用户进程虽然没有轮询,但在内核还是通过遍历的方式来检查 fd 的就绪状态(可通过异步 IO.../linux/posix_types.h: # define __FD_SETSIZE 1024 此外在 Linux 内核中,select 所用到的 FD_SET 是有限的,即内核中有个参数...在 Linux 2.4 内核前主要是 select 和 poll,自 Linux 2.6 内核正式引入 epoll 以来,epoll 已经成为了目前实现高性能网络服务器的必备技术。...以下是一个简单的 Java AIO 示例 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer
所以后面的讨论基本上是讨论 IO 相关的系统调用和文件系统Page Cache的一些机制。 Linux内核中的IO栈 这一小节来看 Linux 内核的 IO 栈的结构。先上一张全貌图[4]: ?...由图可见,从系统调用的接口再往下,Linux下的 IO 栈致大致有三个层次: 文件系统层,以 write(2) 为例,内核拷贝了write(2)参数指定的用户态数据到文件系统 Cache 中,并适时向下层同步...设备层,通过 DMA 与内存直接交互,完成数据和具体设备之间的交互 结合这个图,想想Linux系统编程里用到的Buffered IO、mmap(2)、Direct IO,这些机制怎么和 Linux IO...Page Cache 的同步 广义上 Cache 的同步方式有两种,即Write Through(写穿)和Write back(写回)....对应到 Linux 的Page Cache上所谓Write Through就是指write(2)操作将数据拷贝到Page Cache后立即和下层进行同步的写操作,完成下层的更新后才返回。
Linux 中主要有五种IO模式:阻塞IO, 非阻塞IO, IO 多路复用,信号驱动IO和异步IO; 如果从同步非同步,阻塞非阻塞角度来看,又可以分为:同步阻塞IO, 同步非阻塞IO,异步阻塞IO和异步非阻塞...IO; 每种IO模型,都有自己的使用模式,他们对于特定的应用程序都有自己的优点:其简单分布如下图所示 ?...每种IO模型都有自己的使用场景,他们对于特定的应用程序都有自己的优点; 具体可参考:https://blog.csdn.net/tjiyu/article/details/52959418 XXX TO-DO
线程同步 一、条件变量 1. 同步概念 同步问题是保证数据安全的情况下,让线程访问资源具有一定的顺序性,从而有效避免饥饿问题,叫做同步。 2....也就是同步的解决方案是什么呢?这个解决方案在 Linux 中称为条件变量。 什么叫做条件变量呢?...现在我们就模拟这个场景,对显示器这个共享资源加锁,并添加条件变量实现同步。...它们的作用相同,都是用于同步操作,达到无冲突的访问共享资源目的。 但 POSIX 可以用于线程间同步。 我们一句话总结以前学的信号量,信号量是一个保证 PV 操作的原子性的一把计数器。...例如使用第二种方法判空还是满: (2)原理 但是我们现在有信号量这个计数器,就很简单的进行多线程间的同步过程,就不需要进行判空还是判满了。
同步非阻塞模式(NonBlocking IO) 在非阻塞模式中,发出Socket的 accept()和 read()操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个信息。...= SUCCESS){ } process(buffer); } Java同步非阻塞模式 如上所述,Java的Socket是阻塞模式的典型应用。...* * 此时可以实现非阻塞的IO,但是因为调用了系统底层的阻塞同步IO, * 因此仍然没有从根本上解决问题 * * @Author niujinpeng * @Date 2018/10...整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。...一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。 开发难度相对于阻塞IO模式较难,适合并发小且不需要及时响应的网络应用开发。
本篇介绍 本篇看下Linux如何实现线程安全问题 原子操作 对于基础类型操作,使用原子变量就可以做到线程安全,那原子操作是如何保证线程安全的呢?...linux中的原子变量如下: typedef struct { int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } #ifdef...内存屏障 ARM架构终有3类内存屏障指令: 数据存储屏障(data memory barrier, DMB) 数据同步屏障(data synchronization barrier, DSB) 指令同步屏障...(instruction synchronization barrier, ISB) linux 内核中的内存屏障函数如下: barrier() 编译优化屏障,阻止编译器为了性能优化而进行指令重排 mb...linux中也有对应的方法, 就是持有自旋锁的时候关闭中断,等操作完后再开启,对应的api如下: spin_lock_irqsave(spinlock_t *lock, unsigned long flags
Linux有2个时钟,硬件时钟、系统时钟。
领取专属 10元无门槛券
手把手带您无忧上云