回调函数会触发线程切换么
展开全部
因为传统多线程,即使采用线程池情况下,切换线程也会大量耗费系统资源。一个cpu核心对应一个执行栈,理想情况下线程不切换,只需要设置和cpu核心数一样的线程数是最高效率的。基于这个想法,有两个方案,协程和异步回调方案。
一:协程方案传统多线程切换,由系统控制,采取抢占式多任务策略,线程间切换不可由程序员控制。协程的出发点是由程序员控制线程切换,不由系统控制线程切换,减少线程切换次数,降低线程切换成本。从技术角度上看,协程是一个可以中断再执行的函数,和生成器完全是一样的。协程优点在于,协程在配合异步非阻塞的设计时,面对io问题时能承受比较大的并发量,面对非io问题如计算问题,还是没有多线程优势,因为多线程能利用多核。单进程情况下的协程由于只有一个执行栈是无法利用多核的。协程方案的思路是写代码还是按顺序写,但是遇到io等需要原阻塞等待的系统调用时候,将当前执行栈暂停,保存上下文,让出当前执行栈(执行线程,从语法上看就是yield出去,yield这个词可以看成让出当前线程的控制权),执行其它代码,等io事件完成,然后再找个线程恢复之前的上下文,继续执行。写代码时候,像同步单线程一样写,但是执行上由程序员控制线程切换,配合异步非阻塞的api,可以承受大量io情况下实现并发。二:异步回调方案典型如NodeJS,遇到阻塞的情况,比如网络调用,则注册一个回调方法(其实还包括了一些上下文数据对象)给IO调度器(linux下是libuv,调度器在另外的线程里),当前线程就被释放了,去干别的事情了。等数据准备好,调度器会将结果传递给回调方法然后执行,自始至终都是那一个执行栈(执行线程)。但这种写法的问题就是很容易遇到callbackhell,这种异步非阻塞api配合回调函数的写法有点反人类。程序员还是习惯同步的写法。总结来说:异步回调和协程实现高io并发的原理,就是当遇到代码阻塞时候,就扔出当前的线程(执行栈),让别的需要执行代码执行。异步回调和协程必须要配合异步非阻塞的io调用api使用,才能实现io高并发。异步回调和协程核心设计思想是差不多的。
一:协程方案传统多线程切换,由系统控制,采取抢占式多任务策略,线程间切换不可由程序员控制。协程的出发点是由程序员控制线程切换,不由系统控制线程切换,减少线程切换次数,降低线程切换成本。从技术角度上看,协程是一个可以中断再执行的函数,和生成器完全是一样的。协程优点在于,协程在配合异步非阻塞的设计时,面对io问题时能承受比较大的并发量,面对非io问题如计算问题,还是没有多线程优势,因为多线程能利用多核。单进程情况下的协程由于只有一个执行栈是无法利用多核的。协程方案的思路是写代码还是按顺序写,但是遇到io等需要原阻塞等待的系统调用时候,将当前执行栈暂停,保存上下文,让出当前执行栈(执行线程,从语法上看就是yield出去,yield这个词可以看成让出当前线程的控制权),执行其它代码,等io事件完成,然后再找个线程恢复之前的上下文,继续执行。写代码时候,像同步单线程一样写,但是执行上由程序员控制线程切换,配合异步非阻塞的api,可以承受大量io情况下实现并发。二:异步回调方案典型如NodeJS,遇到阻塞的情况,比如网络调用,则注册一个回调方法(其实还包括了一些上下文数据对象)给IO调度器(linux下是libuv,调度器在另外的线程里),当前线程就被释放了,去干别的事情了。等数据准备好,调度器会将结果传递给回调方法然后执行,自始至终都是那一个执行栈(执行线程)。但这种写法的问题就是很容易遇到callbackhell,这种异步非阻塞api配合回调函数的写法有点反人类。程序员还是习惯同步的写法。总结来说:异步回调和协程实现高io并发的原理,就是当遇到代码阻塞时候,就扔出当前的线程(执行栈),让别的需要执行代码执行。异步回调和协程必须要配合异步非阻塞的io调用api使用,才能实现io高并发。异步回调和协程核心设计思想是差不多的。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询