【译】更新中的 Go 内存模型 Updating the Go Memory Model

当前 go 语言的内存模型是在 2009 年编写成的,后来进行了一些细微的修改,很明显,我们需要为当前的内存模型添加一些细节,这其中包括对竞争检测器明确的背书以及清楚地说明 sync 和 atomic 中的 API 是如何进行同步的。

这一部分我们将重申 Go 的设计哲学和他目前的内存模型,在这之后我将概述我认为我们还应该对 Go 内存模型做哪些细微的调整。它以前面的 硬件内存模型编程语言内存模型 为背景。

我在 GitHub 上开了一个讨论区 来收集关于这部分的意见和反馈。基于这些反馈,我会在本月晚些时候提交一份正式的提案。使用 GitHub 的讨论功能本身就是一场实验,对于重大的变化,我们试图找到一种合理的方式来扩大它的讨论范围。

【译】编程语言内存模型 Programming Language Memory Models

编程语言的内存模型回答了并行的程序可以依赖哪些(硬件)行为以便在线程之间共享内存的问题。例如,考虑以下类 c 程序, 其中 x 和 done 都是从零开始的:

1
2
3
// Thread 1           // Thread 2
x = 1; while(done == 0) { /* loop */ }
done = 1; print(x);

程序尝试将变量 x 的值从线程 1 同步给线程 2,使用变量 done 作为准备好接收消息的信号,如果线程 1 和线程 2 都运行在自己专门的线程上,并且都执行结束,则该程序能保证按预期打印 1 吗?编程语言的内存模型回答了这个问题以及其他类似的问题。

go chan 源码

chan 是 Golang 中内置的数据类型,不像 Mutex 等需要引入,他是 first-class 类型,他在 Go 的并发控制中起着相当重要的作用。chan 的思想来自 Tony Hoare 在 1978 年发表的论文 Communicating Sequential Processes, 它提出了一种并发的编程语言,用来描述并发系统中的互动模式,在后来的演化过程中,才逐渐形成了 CSP 并发模式。CSP 模式中存在 Process/Channel 每个 Process 独立运行,多个 Process 之间通过 Channel 通信。

Go Context 源码阅读

在 Go 服务中,往往由一个独立的 goroutine 去处理一次请求,但在这个 goroutine 中,可能会开启别的 goroutine 去执行一些具体的事务,如数据库,RPC 等,同时,这一组 goroutine 可能还需要共同访问一些特殊的值,如用户 token, 请求过期时间等,当一个请求超时后,我们希望与此请求有关的所有 goroutine 都能快速退出,以回收系统资源。

context 包由谷歌开源,在 Go 1.7 时加入标准库,使用它可以很容易的把特定的值,取消信号, 截止日期传递给请求所涉及的所有 goroutine。

robfig/cron/v3 源码阅读

robfig/cron/v3 是一个 Golang 的定时任务库,支持 cron 表达式。Cron 的源码真实教科书级别的存在(可能是我菜 …),真的把低耦合高内聚体现地淋漓尽致,另外其中涉及的装饰器模式,并发处理等都很值得学习。

【译】硬件内存模型 Hardware Memory Models

很久以前,当人们还在写单线程程序的时候,让程序跑的更快的一个最有效的办法就是什么也不做,因为下一代硬件和编译器的优化会使得程序更快但行为不发生改变。在这个童话般的时代,区分优化是否有效有一个简单的测试方法:如果程序员无法区分一个正确程序经过优化和未经优化的版本之间的(运行结果)差异(除速度更快外)那么优化就是有效的,也就是说,正确的优化不会改变程序的行为。

但是多年前的某一天,硬件工程师们发现让单个处理器越来越快的魔法消失了,与此同时,他们发现了一种新的魔法,这能使得他们创造出拥有越来越多处理器的计算机。操作系统将这种硬件并行性抽象成线程 Threads 暴露给开发者。这种通过操作系统线程提供多处理器(能力)的魔法对硬件工程师很友好,但它给语言设计师、编译器作者和程序员带来了严重的问题。

之前许多在单线程程序中不可见(因此有效)的硬件和编译器优化在多线程程序中变得可见。如果我们说有效的优化不会改变正确程序的行为,那么现在来看只能要么说这些优化是无效的,要么说程序是错误的,我们改如何抉择呢?

【译】Bounds Check Elimination 边界检查消除

Go 是一种内存安全的语言,在针对数组 (array) 或 Slice 做索引和切片操作时,Go 的运行时(runtime)会检查所涉及的索引是否超出范围。如果索引超出范围,将产生一个 Panic,以防止无效索引造成的伤害。这就是边界检查(BCE)。边界检查使我们的代码能够安全地运行,但也会影响一定的性能。

DES 原理与实现

DES是一种对称加密算法【即发送者与接收者持有相同的密钥】,它的基本原理是将要加密的数据划分为n个64位的块,然后使用一个56位的密钥逐个加密每一个64位的块,得到n个64位的密文块,最后将密文块拼接起来得到最终的密文。