原文链接 简介
golang调度器的设计行为能够使你的多线程go程序更有效率、性能更好,这要归功于golang调度器对于操作系统调度器的支持。对于一个golang开发者来说,同时深刻理解操作系统调度和golang调度器工作原理,能够让你的golang程序设计和开发走到正确道路上。 操作系统调度器
操作系统调度器十分复杂,它必须要考虑到底层的硬件结构,包括但不限于处理器数和内核数,cpu cache和NUMA。如果没有这些东西,调度器就没办法尽可能有效的工作。 程序其实就是一系列按顺序执行的机器指令。为了能让其正常干活,操作系统使用了线程的概念。线程会处理和执行分配给它的一系列的机器指令。线程会一直执行这些机器指令,直到没有指令再去执行了。这也是为什么把线程称作"a path of execution"。 每个运行程序都会创建一个进程,每个进程都会有一个初始线程。线程能够创建更多的线程。这些不同的线程独立运行并且调度行为是线程级别决定的,而不是在进程级别。线程能够并发的执行(单独内核上每个线程会轮询占用一段cpu时间),而不是并行执行(在不同内核上同时执行)。线程同时会维持它自己的状态,并且能够在本地安全、独立地执行他自己的指令。这也说明了为什么线程是cpu调度的最小单位。 操作系统调度器,它负责确保在有线程能够运行的时候内核不会空闲下来。它会制造一种假象——所有能够跑的线程此时都在同时执行。为此,调度器需要优先执行高优先级的线程,但是它也必须保证低优先级的线程不会饿死。调度器也必须尽可能将调度延时压倒最少,。 好在许多算法的应用使得调度器更加高效。下面解释一些重要的概念。 执行指令
程序计数器(PC),有时候也叫做指令指针(IP),能够让你找到下一个要执行的指令。大部分的处理器里,PC指向下一个指令。
如果你曾经注意到go程序的追踪栈,你会注意到这些每一行末尾的16进制数字。例如Listing 1里的+0x39和+0x72
Listing 1