阻塞

同步异步、阻塞非阻塞

天大地大妈咪最大 提交于 2021-02-02 04:51:23
同步与异步:一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能完成,这是一种可靠的任务序列。 阻塞与非阻塞:主要是从CPU的消耗上来说的,阻塞就是CPU停下来等待一个慢的操作完成以后,CPU才接着完成其他事情。 同步阻塞:最常用的一种用法,使用也是最简单的,但是I/O性能一般很差,CPU大部分处于空闲状态。 同步非阻塞:提升I/O性能的常用手段,就是将I/O的阻塞改为非阻塞方式,尤其在网络I/O是长连接同时传输数据也不是很多的情况下,提升性能非常有效。这种方式通常能提升I/O性能,但是会增加CPU消耗,要考虑增加的I/O性能能不能补偿CPU的消耗,也就是系统的瓶颈是在I/O还是在CPU上。 异步阻塞:这种方式在分布式数据库中经常用到,例如,在一个分布式数据库中写一条记录,通常会有一份是同步组撒的记录,而还有两至三份备份记录会写在其他机器上,这些备份记录通常都采用异步阻塞的方式写I/O。异步阻塞对网络I/O能够提升效率,尤其像上面这种同时写多份相同数据的情况。 异步非阻塞:这种组合方式用起来比较复杂,只有在一些非常复杂的分布式情况下使用,集群之间的消息同步机制一般用这种I/O组合方式。如Cassandra的Gossip通信机制就是采用异步非阻塞的方式,他适合同时要传多份数据到集群中不同机器,同事数据的传输量虽然不大但是却非常频繁。这种网络I

Java I/O 模型的演进

混江龙づ霸主 提交于 2020-11-27 04:54:55
原文同步至 http://waylau.com/java-io-model-evolution/ 什么是同步?什么是异步?阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O 模型讲起,介绍了5种常见的 I/O 模型。而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 Java I/O 模型来提高系统的并发量和可用性。 由于,Java 的 I/O 依赖于操作系统的实现,所以先了解 Unix 的 I/O 模型有助于理解 Java 的 I/O。 相关概念 同步和异步 描述的是用户线程与内核的交互方式: 同步 是指用户线程发起 I/O 请求后需要等待或者轮询内核 I/O 操作完成后才能继续执行; 异步 是指用户线程发起 I/O 请求后仍继续执行,当内核 I/O 操作完成后会通知用户线程,或者调用用户线程注册的回调函数。 阻塞和非阻塞 描述的是用户线程调用内核 I/O 操作的方式: 阻塞 是指 I/O 操作需要彻底完成后才返回到用户空间; 非阻塞 是指 I/O 操作被调用后立即返回给用户一个状态值,无需等到 I/O 操作彻底完成。 一个 I/O 操作其实分成了两个步骤:发起 I/O 请求和实际的 I/O 操作。 阻塞 I/O 和非阻塞 I/O 的区别在于第一步,发起 I/O 请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞 I/O ,如果不阻塞

Python 开源异步并发框架的未来(转)

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-26 18:41:47
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Python 开源异步并发框架的未来 fantix 1.1k 2014年04月16日 发布 推荐 4 推荐 收藏 31 收藏, 8.9k 浏览 呵呵,这个标题有点大,其实只是想从零开始介绍一下异步的基础,以及 Python 开源异步并发框架的发展和互操作性。 另外,这是我在 OSTC 2014 做的一个 20140330-OSTC-分论坛1王川 http://v.youku.com/v_show/id_XNjk2ODI0ODQ4.html ,幻灯片在 这里 ,欢迎拍砖。 开源 Python 是开源的,介绍的这几个框架 Twisted 、 Tornado 、 Gevent 和 tulip 也都是开源的,最后这个演讲是在开源大会弄的,所以标题里肯定少不了开源。另外,我的 gevent3 项目也是开源的——貌似不少同学被我起的极品名字给搞混了,特别说明一下, gevent3 虽然有跟 Gevent 一样的接口外貌,但底层却是 tulip 驱动的(考虑把名字改回 gulip 之类的);请区别于将来会支持 Python 3 的 Gevent 1.1。 非阻塞 先上一段代码。请原谅我用 Python 代码充当伪代码了,但 Python 的语法实在是太简单了,忍不住啊。 import sockets = socket

如何优雅的控制goroutine的数量

放肆的年华 提交于 2019-12-09 22:16:56
1,为什么要控制goroutine的数量? goroutine固然好,但是数量太多了,往往会带来很多麻烦,比如耗尽系统资源导致程序崩溃,或者CPU使用率过高导致系统忙不过来。比如: for i:=0; i < 10000; i++ { go work() } 2,用什么方法控制goroutine的数量? 要在每一次执行go之前判断goroutine的数量,如果数量超了,就要阻塞go的执行。第一时间想到的就是使用通道。每次执行的go之前向通道写入值,直到通道满的时候就阻塞了,如下: var ch chan int func work() { //do something <-ch } func main() { ch = make(chan int, 10) for i:=0; i < 10000; i++ { ch <- 1 go work() } } 这样每次同时运行的goroutine就被限制为10个了。但是新的问题出现了,因为并不是所有的goroutine都执行完了,在main函数退出之后,还有一些goroutine没有执行完就被强制结束了。这个时候我们就需要用到sync.WaitGroup。使用WaitGroup等待所有的goroutine退出。如下: var wg *sync.WaitGroup func work() { defer wg.Done() //do

NIO与JDBC的再思考:同步与阻塞在论域上的根本区别

风格不统一 提交于 2019-12-04 19:03:43
JDBC中STATEMENT的执行是同步的。但是非阻塞的。即,不同的STATEMENT间并不会互相阻塞。这一点与NIO是相似的。 同步的论域是纵向的。它表达的是模块间的协作模型。 阻塞的论域是横向的。它表达的是线程间的协作模型。维基上的解释也是这样的:http://en.wikipedia.org/wiki/Non-blocking_algorithm: ...The traditional approach to multi-threaded programming is to use locks to synchronize access to shared resources... 两者的语义都是动态的。模块协作与线程协作都是运行时语义。分别用来描述程序或系统内的纵向与横向协作。模块协作肯定是分时间进行的。而线程协作却有可能是或至少可以看成是同时进行的。 如果JDBC CONNECTION类的的所有STATEMENT操作都是非阻塞的,那么意味着同一个连接的STATEMENTS可以同时进行它们的动作。这样的话,就没有必要一定要用多个连接去连接同一个数据库。 如果用一个连接就可以达到同时即并发与数据库通信的目的,那我为什么要用连接池呢?特别是在并不存在任何事务性需求的环境下? 来源: oschina 链接: https://my.oschina.net/u/109289/blog