注意,相关但不相同:iPhone - Grand Central Dispatch main thread
我多次在这个问题上失败了,所以这里是源代码:
在主线程上
dispatch_async( dispatch_get_main_queue(), ^{ NSString * str = @"Interrupt myself to do something."} );
我只是很好奇,当一个线程切换时,它将其寄存器存储在线程本地存储中,切换上下文,从程序计数器中的新位置运行(我假设它位于只使用一个程序的程序副本中)不同的堆栈和寄存器),然后它“回到”主线程。
当它中断自身时,我只是想知道什么时候该决定,以及Thread Local的内容会发生什么。
我已经阅读了一点,但我仍然围绕着程序不连续这一事实。当操作系统决定运行一个进程块或其块(线程)时,它们只是“在小块中做的事情。”
我是自学成才,这可能会增加我缺乏注册/ asm知识,这可能是任何学者的标准。
感谢。代码应该有帮助,这是iOS特定的,但我相信答案/问题与从主要到主要的任何语言有关。
由于每次过去的尝试都会导致冗长的答案,而忽略了我问这个问题的原因,我会最后一次迭代....
这是针对SAME线程的。主要对主。它真的只是停止了自己,将程序计数器移到其他地方,去,然后在街区结束?这些东西通常也不会在分支处发生变化(if / for和blocks)。
指出我正确的方向也有效,但就像我说的那样,之前这个问题被误读了。
答案 0 :(得分:1)
如果没有GCD内部的访问权限就很难回答你的问题,但一般来说,答案是否定的,只是将一个工作单元添加到调度队列中就不会立即中断正在执行的代码。
正如您所建议的那样,上下文切换非常昂贵,不仅仅是在状态保存方面。恢复,但处理器将需要转储指令管道,导致浪费周期。
通常,操作系统将继续执行当前任务,直到它暂停(例如,等待网络或其他IO操作)或者可能被某些外部事件(按下手机上的主页键)中断,但也有时间限制以防止失控的任务锁定整个设备(这是先发制人的多任务处理,而不是任务需要放弃CPU的合作多任务处理)
使用dispatch_async,无法保证代码何时与当前代码块相关。代码块甚至可能不在队列中的下一个 - 其他线程可能在此之前已将其他工作单元添加到队列中。
答案 1 :(得分:0)
我认为令你感到困惑的是使用spark.createDataFrame(rdd, schema)
# res1: org.apache.spark.sql.DataFrame = [1: int, 2: int ... 8 more fields]
,它提交代码在主线程的队列上运行。
当你致电dispatch_async( dispatch_get_main_queue())
时,它会在主队列中添加一个工作单元,从主线程运行它的作业。
如果从主线程运行此调用,结果是相同的。该工作将添加到主队列中以供以后处理。
当您从主线程进行此调用时,系统不会检查主队列的工作,直到您的代码返回为止。
将此视为一个厨师厨房。当厨师工作时,他把盘子放在洗碗区。他不会停下来做菜,直到他达到他目前所做的突破点。此时,他拿起一盘菜,装入洗碗机,然后回去做饭。
厨师知道每次到达断点时都必须检查菜肴,然后在返回烹饪前完成洗碗任务。
对后台队列的dispatch_async调用就像一个2人厨房。洗碗机同时工作。厨师将一盘餐具放入洗碗台(队列),洗碗机(另一个线程)在完成之前的任务后立即完成任务,而厨师继续致力于烹饪。
以上假设一台机器具有多个处理器,这是当前的常态。每个处理器可以同时工作,而不必处理多个任务。
如果您在具有抢占式多任务处理的单核系统上运行,则将任务提交到单独的线程/后台队列与具有多个处理器的效果相同,但现在操作系统必须执行一项杂耍操作。厨房里只有一个人,但他戴着多个帽子。这个人正在做厨师工作,操作系统大喊“切换!”#34;厨师记下他正在做的事情(保存状态),然后跳进洗碗池并开始洗碗,并继续洗碗,直到操作系统大喊“切换!”#34;再一次,工作人员再次保存状态,切换到下一个角色,然后选择离开它的角色(厨师)。
单核系统上的多任务处理成本更高,因为每次工作人员切换角色时,都必须保存当前状态,然后为另一个角色加载已保存的状态,然后继续。那些上下文切换需要时间。