goroutine 调度器

对golang的goroutine的内部实现感觉非常神秘,通过这段时间的学习基本了解了golang调度器实现原理。

golang调度器

虽然golang的最小调度单元为协程(goroutine),但是操作系统最小的调度单元依然还是线程,所以golang scheduler(golang调度器)其要做的工作是如何将众多的goroutine放在有限的线程上进行高效而公平的调度。

操作系统的调度不失为高效和公平,比如CFS调度算法,那么go为何要引入goroutine?原因很多,有人会说goroutine 相比于linux的pthread机制使用很方便。但是核心原因为goroutine的轻量级,无论是从进程到线程,还是从线程到协程,其核心都是为了使得我们的调度单元更加轻量级,我们可以轻易得创建几万几十万的goroutine而不用担心内存耗尽等问题。golang引入goroutine试图在语言内核层做到足够高性能得同时(充分利用多核优势、使用epoll高效处理网络/IO、实现垃圾回收等机制)尽量简化编程。

ps:人类社会的发展是生产工具不断发展解放生产力的过程,语言的发展也是一样,从机器语言到汇编语言、C语言、面向对象C++\ Java以及到现在层出不穷的动态语言。编程语言作为生产工具,其发展核心目的为最大化IT工作人员的生产力。从这点看,我很看好go语言,极简得编程之道简直大爱。

以下基于Daniel Morsing的一篇文章介绍goroutine调度器。

首先基于线程,用户态协程可以选择以下3种调度机制。

N:1 即多个用户态协程运行在一个os线程上,这种方式的优点是可以很快得进行上下文切换,但是缺点是不能利用多核优势。

1:1 一个用户态协程对应一个os线程,这种方式得优点是可以利用到多核的优势,但是协程的调度完全依赖于os线程的调度,而os线程的调度的上线文切换的代价又比较大,从而导致这种模型调度的上下文切换代价比较大。

M:N golang scheduler 使用的m:n调度模型,即任意数量的用户态协程可以运行在任意数量的os线程上,这样不仅可以使得上线文切换更加轻量级,同时又可以充分利用多核优势。 为了实现这种调度机制,golang 引入如下3个大结构

阅读更多

存储一致性之复制

难得一见的关于分布式理论系列文章,非常之精彩,通读这一系列文章,发现作者没有站在专家的立场上以复杂得方式分析复杂的问题,而是从工程师的角度非常恰当得介绍一系列分布式的理论,对分布式理论各个方面总结概括得非常到位,令人赏心悦目。

阅读更多

存储系统一致性与可用性(二)

一个分布式kv引擎中使用的一致性协议

发现现在很多开源系统在高可用,性能,可扩展性等很多方面没有一个很完善的方案。希望设计一个 k/v 存储系统,系统支持强一致性,并且在 C,A,P 这三方面都较为均衡,系统具有一定可扩展性。

阅读更多

存储系统一致性与可用性

1. 关于可用性

提供系统可用性的关键是在相关组件失效情况下,系统能多快恢复并继续正确得提供服务。

1.1 如何恢复服务

How to recover a single node from power failure。

阅读更多

Nginx And Go Http 并发性能

1 测试硬件

1
2
3
Intel(R) Xeon(R) CPU X3440 @ 2.53GHz
cpu cache size : 8192 KB
DRAM:8G

阅读更多