协程解决异步回调的问题,你知道吗?(上)

实际上不是使用阻塞 api,而是使用这个 api 的异步等效项。例如线程是io密集型吗,您可能需要等待硬盘 io 到位。现在您可以在发出请求后切换到另一个协程,并等待读取完成后再继续。

原则上,非协程程序也可以这样写,但往往更复杂。通过一些封装,每个协程的内部都与普通程序大致相同。我认为这是使用协程的主要优势。线程的存在允许程序在多个 CPU 上一起执行。和使用协程不冲突,所以go其实是一个m:n的协程设计。

图片[1]-协程解决异步回调的问题,你知道吗?(上)-4747i站长资讯

协程是一个轻量级的用户模式线程。它的上下文切换可以简单的认为是在不进入内核态调用的情况下执行了几次。熟悉OS的朋友应该都知道,一次的开销是比较大的,所以协程切换的开销比线程切换要小很多,而且协程的总数不再受制于所控制的线程数操作系统内核状态,所以它可以在数百万的数量级上完成。

协程可以轻松实现上万并发,具体看具体场景。比如:一个同步阻塞的redis单连接的并发上限是几千,而一个异步的非阻塞redis单连接可能有10w+并发多线程是io密集型吗,多很多倍^_^!在这里,异步回调的问题可以通过协程来解决。

协程应用在纯计算场景应该不常见,解决阻塞IO场景比较常见。协程切换主要有两个接口:yield和. 理论上,用户可以随心所欲地使用它们,无论场景是什么:IO 阻塞或非阻塞、IO 密集型或 CPU 密集型。

图片[2]-协程解决异步回调的问题,你知道吗?(上)-4747i站长资讯

遇到阻塞API,很多人都是通过多线程来解决的,还有其他的解决方法。

方案A:钩子技术,将同步阻塞api设置为非阻塞异步,然后模拟串口操作,发送命令立即返回,切换到其他协程,等待回复,再切换回协程发送又是一个;方案B:如果接收方支持异步,可以封装一组异步接口,然后通过协程进行调度。当然,工作量有点大,因为接收者可能很多。

最好的情况。上面第三点已经说过了,就是想办法用异步阻塞代替同步阻塞操作,当然中间需要事件驱动的辅助,比如epoll,挂fd就可以了,然后切换协程,一直等到回调结果切换回来,本质上是一个异步操作。此外,还有更多的协程可以切换,让用户可以避免异步回调的反人类操作。当然,在这个框架下,使用多线程来使用多核资源并没有错。无论如何,它本质上是一组异步回调。

图片[3]-协程解决异步回调的问题,你知道吗?(上)-4747i站长资讯

然后 vert.x 无法阻止。如果是纯计算,复杂度高,就得离开交了。vert.x 将使用虚拟线程将原本阻塞的 io 操作变为非阻塞。见越说后续打算用.get,这是线程上下文中的阻塞api,但是在虚拟线程上下文中,是非阻塞api,即.get会变成.get。 await,比较简单

有很大的不同吗?性能上差别不大,或者vert.x应该表现更好,但是在web的场景下,有了无脑虚拟线程,开发会更容易,有些人学不会await。操作复杂,非阻塞他无法判断,所以在使用vert.x的时候,我有个小想法,就是招安卓人做vert.x,往往安卓开发用vert.x上手比较快,并且更容易等待。熟悉TG:

文章来源:https://www.163.com/dy/article/GTGRSAIL0552PD5Y.html

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享