当前位置: 首页>編程日記>正文

同步回调与异步回调区别

同步回调与异步回调区别

引言

首先说说在单核时代,异步回调应该也没有人会去使用,因为从CPU执行上来说异步回调除了不像同步回调那样执行时阻塞(阻止后面代码执行,即仍处于调用callback的线程的上下文中)外,可能与同步回调也差不多,最多可能做到一个关注点的分离,这意味着在单核时代我们几乎总是使用同步回调.但随着多核时代的到来,异步的优势慢慢体现,接下来就简单谈谈这两者之间的区别.

孰优孰劣

首先对于这两种方式本身来说没有一种是"更优"于另一种的,它们都有更适合于自己的场景,并不能一概而论,

同步回调

  1. 可以无竞争的访问线程本身的元素,比如thread_local,或者线程栈上元素.
  2. 触发回调和回调执行是同一个线程,不需要关系线程安全,直接执行函数即可.
  3. 代码编写简单

异步回调

  1. 触发回调和回调执行并不是一个线程,需要注意DataRace,需要我们进行指定执行顺序(互斥锁或指定内存序以到达同步).
  2. 不能访问thread_loacl和栈上元素
  3. 对于执行callback的线程来说的性能提升,异步回调意味着我们可以把耗时的IO操作全部放到其他线程执行,而我们本身的时间循环可以继续执行正常的逻辑,以此提升并发量.

有一句话很有意思,即同步回调 (sync callback) 在 构造闭包 的 调用栈 (call stack) 里 局部执行,这意味着同步回调中上下文的寿命一般长于用lambda表达式捕获后构造的回调,这使得我们不必担心捕获对象的生命周期问题,而异步回调往往闭包的寿命长过调用栈的长度,这使得其中捕获的对象可能在函数执行时已经死亡,同时对象也可能泄露,这类问题是有一个通解的,即shared_ptr/weak_ptr.

关于回调中对象的所有权问题有一点值得讨论,即强引用(strong reference),这时闭包是拥有对象的所有权的,闭包何时被销毁,对象也何时被销毁,这用在我们希望回调执行时捕获对象总是有效.例子是用bind捕获shared_ptr,此时shared_ptr的生命周期等同于bind产生的对象(外界不存在引用计数的话).

所以我们不能一概的指出到底哪一个更好,举个简单的例子

std::foreach(callback);

此时这就是一个同步回调,在这种场景下我们也兵不需要异步回调.

while(Event_Driven_loop){if(connectionEvent){//dosomething}else if(IOEvent Event){blockingqueue.push(Event);}else if(CalculateEvent Event){blockingqueue.push(Event);}...
}

以上是一个事件驱动的循环,根据事件类型来执行不同的代码,当遇到计算任务和IO任务的时候,费时的操作我们可以扔到一个阻塞队列或者类似的工具中,这就是一个典型的异步回调,这样的好处时费时的操作可以不在宝贵的时间循环中进行,而开辟出专门的线程去做这件事,以此提升并发潜力.想象以下如果这个我们改成一个同步回调,那么如果在Event中有一个费时的操作,文件IO也好,DNS解析也好,又或是一个花费半秒的计算任务,这对于一个高性能的服务器来说是不可忍受的.

最后就是其实同步回调和异步回调本身实现的东西让人感觉和模板模式(同步),观察者模式(异步)很类似,都是通过注册回调去实现复用和扩展,无非是使用了不同的方式而已,其实做到的事情都差不多,按照OS的设计理念来说就是机制与策略相分离。

而观察者模式又和责任链模式很类似,前者给人的感觉像是特殊的责任链模式(甚至可以组织成一个观察者链,与责任链的区别 就是消息是否可变),当然前者更偏向于观察者(订阅者)状态的改变,后者更偏向于链中的逻辑执行。所以很多时候私以为不要陷入理论的束缚,而是从实际出发,不然就有些本末倒置的感觉了。

总结

其实大可不必纠结名词的含义,根据上面两个例子我们可以看出这其实就是问题的两种解决方案,各有优劣而已,无非是时机不同我们所的需求不同罢了.

参考:

  1. https://blog.csdn.net/yunnysunny/article/details/44726963
  2. 再谈回调 一篇好文
  3. 极客时间 设计模式之美


https://www.fengoutiyan.com/post/13783.html

相关文章:

  • 同步api和异步api
  • 异步回调api安全设计
  • 前端同步和异步的区别
  • 异步和回调
  • js异步
  • 异步执行和同步执行
  • 同步访问和异步访问
  • 异步回调
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機