范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

同步异步多线程这三者关系,你能给面试官一个满意的回答吗?

  前几天一位朋友去面试,面试官问了他同步,异步,多线程之间是什么关系,异步比同步高效在哪?多线程比单线程高效在哪?由于回答的不好,让我帮他捋一下,其实回答这个问题不难,难就难在只对别人说理论,而没有现杀的例子。一:异步1. 到底解放了谁? 从基础的同步说起
  要说解放了谁,一定得有几个参与者,举个例子:当你的主线程读取一个应用程序之外的资源时,它有可能是一个文件,又有可能是一个外部服务,当用同步方式读取外部服务时,首先主线程会从用户模式进入到内核模式,在内核模式中windows会将你的请求数据交给对应的网络驱动程序,继后会让这个线程进入休眠状态,当网络驱动程序和外部服务一阵痉挛之后,网络驱动程序会将获取到的结果交给当初休眠的线程,windows唤醒休眠线程继而执行后续的C#代码,画个简图理解一下,不一定全对。
  这里就存在着一个非常大的问题,步骤4-步骤7之间,你的主线程一直都是休眠状态,比如在GUI编程中,有一个重要的原则就是解放你的UI线程(主线程),所以解决这个问题就迫在眉睫。 异步方式下的处理方案
  说到这里,大家应该知道了异步方式就是为了解放主线程,又可以叫调用线程,没错,接下来看一下同样的场景在异步中如何处理的。
  从图中可以看到,步骤三中将thread数据交给网络驱动程序之后,该thread就直接返回不管了,当后续网络驱动程序获取数据后,将数据丢给CLR线程池中的IO线程再由它触发你的回调函数。 总结
  异步相比同步效率高就高在解放了调用线程,在驱动程序和远程服务RoundTrip期间,调用线程还可以执行其他工作,放在GUI上就是主线程可以继续响应用户的超敏操作。
  由于没有空转的线程,CPU可以得到最满载的运转,更少的线程就有更少的线程栈空间,更少的GC回收时间和上下文切换。2. 代码演示
  还是那句话,光说可不行,你得上一点代码看看,有了上面的理论基础,这里我就模拟爬取下博客园首页的所有文章的用户头像。 同步代码        public static void Main(string[] args)         {             SingleThreadDownloadImages();             Console.WriteLine("主线程继续执行其他的咯~~~");             Console.Read();         }          public static void SingleThreadDownloadImages()         {             using (var client = new HttpClient())             {                 //调用线程 空转等待…                 var content = client.GetStringAsync("http://cnblogs.com").Result;                 var html = new HtmlDocument();                 html.LoadHtml(content);                  var imgsrcList = html.DocumentNode.QuerySelectorAll("img.pfs").Select(m => m.Attributes["src"].Value)                                                   .ToList();                  Console.WriteLine(#34;准备下载:{imgsrcList.Count}个...");                  for (int i = 0; i < imgsrcList.Count; i++)                 {                     //调用线程 空转等待…                     var stream = client.GetStreamAsync(imgsrcList[i]).Result;                      Image.FromStream(stream).Save($@"C:2{i}.jpg");                 }             }             Console.WriteLine("SingleThreadDownloadImages 执行结束");         }  ------ output ------  准备下载:19个... SingleThreadDownloadImages 执行结束 主线程继续执行其他的咯~~~   异步代码        public static void Main(string[] args)         {             AsyncDownloadImages();             Console.WriteLine("主线程继续执行其他的咯~~~");             Console.Read();         }          public static async void AsyncDownloadImages()         {             using (var client = new HttpClient())             {                 var content = await client.GetStringAsync("http://cnblogs.com");                 var html = new HtmlDocument();                 html.LoadHtml(content);                  var imgsrcList = html.DocumentNode.QuerySelectorAll("img.pfs").Select(m => m.Attributes["src"].Value)                                                   .ToList();                  Console.WriteLine(#34;准备下载:{imgsrcList.Count}个...");                  for (int i = 0; i < imgsrcList.Count; i++)                 {                     var stream = await client.GetStreamAsync(imgsrcList[i]);                     Image.FromStream(stream).Save($@"C:2{i}.jpg");                 }                  Console.WriteLine("AsyncDownloadImages 执行结束");             }         }  ------ output ------  主线程继续执行其他的咯~~~ 准备下载:19个... AsyncDownloadImages 执行结束
  从结果可以看出,异步在获取图片期间,主线程还可以做其他事情,这就是异步最大的特点。3. windbg 提取是否真为线程池io线程
  其实在图2中我口口声声的说是线程池中的IO线程回调了你的函数,大家先要明白一个概念,线程池中有两种类别的线程,一个是工作线程,一个是IO线程,而工作线程常常就是我们通过代码进行操控,IO线程通常由底层CLR接管,常常用于处理外部资源的操作,如下ThreadPool的GetMaxThreads方法。    public static void GetMaxThreads(out int workerThreads, out int completionPortThreads);
  有了这个基础,再将 AsyncDownloadImages方法修改如下,抓取一下dump文件                var content = await client.GetStringAsync("http://cnblogs.com");                 Console.WriteLine(#34;已获取到:{content.Length}个字符");                 Console.ReadLine();
  ~*e !clrstack 查看所有托管线程的调用堆栈0:000>  ~*e    !clrstack OS Thread Id: 0x62d8 (13)         Child SP               IP Call Site 000000da9b1fd1e8 00007ff9fc7bb4f4 [GCFrame: 000000da9b1fd1e8]  000000da9b1fd308 00007ff9fc7bb4f4 [GCFrame: 000000da9b1fd308]  000000da9b1fd368 00007ff9fc7bb4f4 [HelperMethodFrame_1OBJ: 000000da9b1fd368] System.Threading.Monitor.Enter(System.Object) 000000da9b1fd460 00007ff9e42f8aff System.IO.TextReader+SyncTextReader.ReadLine() 000000da9b1fd4c0 00007ff9e40f0d98 System.Console.ReadLine() 000000da9b1fd4f0 00007ff985c81559 ConsoleApp2.Program+d__3.MoveNext() [C:dreamCsharpConsoleApp1ConsoleApp2Program.cs @ 93] 000000da9b1fd690 00007ff9e388cef2 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 000000da9b1fd760 00007ff9e388cd75 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 000000da9b1fd790 00007ff9e38fbe2f System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run() 000000da9b1fd7e0 00007ff9e3901343 System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action, Boolean, System.Threading.Tasks.Task ByRef) 000000da9b1fd830 00007ff9e3865f40 System.Threading.Tasks.Task.FinishContinuations() 000000da9b1fd8c0 00007ff9e3865a88 System.Threading.Tasks.Task`1[[System.__Canon, mscorlib]].TrySetResult(System.__Canon) 000000da9b1fd900 00007ff9e3865a05 System.Threading.Tasks.TaskCompletionSource`1[[System.__Canon, mscorlib]].TrySetResult(System.__Canon) 000000da9b1fd940 00007ff9c88311a3 System.Net.Http.HttpClient+c__DisplayClass31_0`1[[System.__Canon, mscorlib]].b__1(System.Threading.Tasks.Task`1) 000000da9b1fd990 00007ff9e38f9d47 System.Threading.Tasks.Task.Execute() 000000da9b1fd9d0 00007ff9e388cef2 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 000000da9b1fdaa0 00007ff9e388cd75 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 000000da9b1fdad0 00007ff9e38fa001 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef) 000000da9b1fdb80 00007ff9e38f96e1 System.Threading.Tasks.Task.ExecuteEntry(Boolean)
  !threads 查看编号13的线程类型 0:013> !threads ThreadCount:      8 UnstartedThread:  0 BackgroundThread: 5 PendingThread:    0 DeadThread:       2 Hosted Runtime:   no                                                                                                         Lock          ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception    0    1 5754 000001e2be060f80    2a020 Preemptive  000001E2BFD19868:000001E2BFD19FD0 000001e2be053bb0 1     MTA     6    2 65e0 000001e2be08bd00    2b220 Preemptive  0000000000000000:0000000000000000 000001e2be053bb0 0     MTA (Finalizer)     9    3  25c 000001e2d8435ef0  102a220 Preemptive  0000000000000000:0000000000000000 000001e2be053bb0 0     MTA (Threadpool Worker)  XXXX    4    0 000001e2d845ea30  1039820 Preemptive  0000000000000000:0000000000000000 000001e2be053bb0 0     Ukn (Threadpool Worker)    12    6 23fc 000001e2d8469ea0  202b220 Preemptive  000001E2BFD1E188:000001E2BFD1FFD0 000001e2be053bb0 1     MTA    13    7 62d8 000001e2d8475e20  a029220 Preemptive  000001E2BFD9D588:000001E2BFD9F250 000001e2be053bb0 0     MTA (Threadpool Completion Port)  XXXX    8    0 000001e2d847a0b0  8039820 Preemptive  0000000000000000:0000000000000000 000001e2be053bb0 0     Ukn (Threadpool Completion Port)    14    9  6e4 000001e2d847de70  8029220 Preemptive  000001E2BFD80D88:000001E2BFD81F10 000001e2be053bb0 0     MTA (Threadpool Completion Port)
  其中的 13 7 62d8 000001e2d8475e20 a029220 Preemptive 000001E2BFD9D588:000001E2BFD9F250 000001e2be053bb0 0 MTA (Threadpool Completion Port) 可以明显的看到是 Threadpool Completion Port,没有骗你吧,。二:多线程
  相比单线程,多线程用更多的CPU和更多的线程资源换取更快的计算时间,是一种经典的空间换时间策略,代码就不上了,相信多线程大家都快用烂了。三:总结1. 多线程比单线程高效的原因就是利用了CPU的多核计算把一个大的任务分而治之从而加速任务计算。2. 异步比同步高效的原因是前者释放了调用线程,让调用线程可以做更多的事情而不至于被windows强制休眠浪费线程资源。

还记得那个重复周期的快速射电爆发(FRB)吗?成因仍是个谜在进行了新的无线电观测后,天文学家已经排除了对一个特别奇怪的重复空间信号周期性的主要解释。这个信号就是神秘的FRB20180916B,它以16。35天的周期重复。根据现有的模型,这乌贼不可思议的大脑里有着似乎永不褪色的记忆你还记得上星期二晚饭吃了什么吗?去年的今天呢?我肯定是记不得了。但事实证明,乌贼可以做到,而且一直到老年都可以。这是我们发现的第一种不会随着时间的推移而出现记忆功能退化的动物。在人首款实时水洗自清洁机器人,期待UONI由利A1Pro给出诚意好价只要是稍微关注下智能家居,就会发现国内市场已经高度同质化,在这样的背景下内卷肯定是少不了的。在这个要么拼价格要么拼技术的时代,虽然利好消费者,但要在众多产品中挑选出合适的,也不是件联合国环境规划署宣布全世界正式摆脱含铅汽油这一声明标志着,对100年前汽车行业做出的致命决定,历经数十年的斗争的结束。联合国环境规划署周一宣布,全世界已正式禁止使用含铅汽油。这种危险燃料的使用已经持续了很长时间,这一天终于全国最奇葩的五大停车场都在这里,没点技术您还真出不来今天给大家说点好玩的,汽车是越来越多,停车位成为了香饽饽,真可谓是开车十分钟,停车半小时,所以停车场成为车主们的最后一道防线。而今天咱就给大家盘点全国最奇葩的五大停车场,没点技术您旧机升级iOS14。7会更耗电吗?6款iPhone机型可能会力明显提升iPhone7升级iOS14。7最新版本,整体的电池搜寻到最明显发现,比iOS14。6版累积26分钟。苹果于本奥迪向(720)iPhone用户发布iOS14。7新版系统,除了支持新Oppo推出屏下前置摄像头技术预计明年苹果将放弃iPhone刘海,并为其前置TrueDepth摄像头阵列采用打孔设计。与此同时,Android制造商Oppo继续宣传其屏幕下摄像头技术的新版本。Oppo于2019入手二手iPhone最佳时期又到了!附选购指南(2021年10月)十三香究竟该如何理解?第一个问题,十三香吗?对于只考虑新机的用户,今年增容减价的操作确实完全没理由再买上一代。由此衍生到第二个问题,需要冲Pro系列吗?归根结底就这么四个差距A15澳大利亚甘蔗蟾蜍的蝌蚪正在疯狂同类相食,幼崽只能加速进化在澳大利亚,入侵物种甘蔗蟾蜍孵化出来的幼崽,根本没有机会对抗它们最致命的捕食者同类相食的蝌蚪。它们狼吞虎咽地吃着刚孵化出来的幼崽,就像在吃自助餐一样。但现在,孵化出来的幼崽们正在反一种可重复使用的亚轨道太空飞机原型机成功完成试飞据悉,Dawn航空航天公司已成功完成了其无人驾驶MkIIAurora亚轨道太空飞机原型机,在新西兰南岛格伦坦纳机场上空的五次试飞。这些试飞是由新西兰荷兰太空运输公司于2021年7月神奇的进化结果这就是缓步动物的行走方式水熊虫等缓步类动物无疑是很神奇的。把它们脱水成透明玻璃状,然后再用枪将它们射出去,一旦你给它们补水,你还能得到一个活着的生物。它们的外部也不是唯一坚硬的东西,去年科学家发现它们也有
电池巨头向宁德时代下挑战书很快击败你电动知家消息,近日来自韩国先驱报消息,韩国动力电池巨头LG新能源首席执行官权英寿在一场线上媒体发布会上表示在电动汽车电池市场的全球竞赛中,LG新能源将很快击败中国竞争对手宁德时代。索尼36亿美元收购Bungie主机游戏厂商未来如何竞夺市场?本报记者陈溢波吴可仲北京报道游戏圈的并购大戏正接二连三地上演。春节前,微软宣布以近700亿美元收购动视暴雪,创游戏行业收购金额新高。近日,主机游戏市场上的大玩家索尼也开启了并购动作大学毕业之后所有手机花费从2011年大学毕业,至今2022年,在记忆中的手机一共换了19部,总共花费了27482元,还不算想不起来的,平均换机周期5。5个月。这两天还想着换个小米10S,8256的2299如何使用零信任安全技术对抗内外威胁简介零信任安全技术重新定义了组织动态查看和处理安全威胁的方式。随着勒索软件和网络钓鱼攻击日益增多,很明显人们可以在组织内部找到大量的攻击媒介,并不像行业之前认为的那样在网络边界的内与欧盟隐私协议谈判受阻,Meta或关闭欧洲脸书平台近日,Meta和欧盟委员会因用户数据回传问题僵持不下,前者在提交给美国证券交易委员会的年度报告中指出,若其用户无法将个人数据储存在美国服务器上,那么该公司可能将无法向欧洲提供产品和烧掉3000亿后,国产京东方终于成为全球第一,但为何赚不到钱?点击关注,每天精彩不断!导读烧掉3000亿后,国产京东方终于成为全球第一,但为何赚不到钱?众所周知,随着智能手机电脑等各种电子数码产品的快速发展,我们对液晶显示屏幕的需求也在不断增跳水2200元?联想电竞手机清库存,12256GB降至白菜价联想2020年开辟拯救者电竞手机产线,从春节官宣直到当年8月发布,创造预热时间最长纪录。时间过去一年半左右,官方迎来清库存降价处理,12256GB版本从首发价4199元降至1999又一个国产5G芯片问世,预计今年实现量产,性能达到主流水准这两天,又一个国产5G芯片问世,成功的吸引了大家的眼球,不过这款5G芯片严格来说,不是给手机使用的,那可能有人会问了,不是5G芯片吗?对,没错,是5G芯片,所以,今天我们就来聊聊这微信一哥坐不住了?阿里社交黑马崛起,坐拥4亿用户,厉害了微信作为国内最大的社交软件,有着庞大的基础用户数量,由于其页面简洁操作简单,更是成为了国民最爱的社交软件。虽然微信在社交领域当中的地位是比较高的,可是阿里巴巴集团转攻社交领域并且打滴滴司机每月收入过万,很多人却退出了行业,这是为什么?所谓滴滴司机每月过万收入其实就和外面小哥一样,都是加班加点干出来的,这其中的压力不是一般人能够承受的。而且这个收入很不稳定,高的时候可能过万,低的时候也就几千,从早忙到晚一天不着家滴滴裁员来袭!两轮车网约车货运中台总部区域滴滴裁员来袭!两轮车网约车货运中台总部区域!新年伊始,滴滴出行裁员还是来了。经多方面与内部人士获取信息,相关情况如下裁员指标(优化指标)已开始分部门陆续下发,有些部门已经开始谈了裁