Neil

Rust Ownership System

四个链接初识 Ownership:

  1. [Ownership][1]
  2. [References and Borrowing][2]
  3. [Lifetimes][3]
  4. [Rust语言入门、关键技术与实战经验][5]

一个链接知道 Mutability:

  1. [Mutability][7]

You may have one or the other of these two kinds of borrows, but not both at the same time:

  • one or more references (&T) to a resource,
  • exactly one mutable reference (&mut T).

三个链接理解 Ownership:

  1. [Rust Means Never Having to Close a Socket][6]

  2. [Wrapper Types in Rust: Choosing Your Guarantees][8]

  3. [Fearless Concurrency with Rust][4]

In Rust, having &mut access to the relevant locations at the same time guarantees atomicity of updates to them, since no other thread could possibly have concurrent read access.

Rust instead uses ownership and borrowing to provide its two key value propositions:

  • Memory safety without garbage collection.
  • Concurrency without data races.

... ...

Read more →

理解 Goroutine & Gosched

Goroutine

大家都知道一个编译好的 Go 程序一般都在 2MB 以上,那是因为 Go 编译器把 Go 的运行环境(runtime)也编译进去了。 一个完整的 Go 程序结构可以表示为下图:

图1 出自 [7]

在 [Analysis of the Go runtime scheduler][7] 中作者们写道:

我们写的 Go 程序运行在 runtime 之上,当我们要调用 system call 时,runtime 会帮我们与系统打交道。Runtime 有一个 scheduler,它与系统的 scheduler 类似,但不同点是它调度不是系统线程而是 goroutine,而且它是运行在用户空间中(用 intel 的术语来说就是 ring3)。

Goroutine 与系统线程的对应关系是 N:M,多个goroutine对应多个系统线程,一般来说 gouroutine 的数量远多于系统线程。Goroutine 的运行依托于系统线程,一个线程在这一时刻执行的这个 goroutine,在另一时刻由于 runtime 的调度执行的可能又是另外一个 goroutine。 从系统的角度看,一个 Go 程序就是一个进程,这个进程中有多个线程,但是系统不知道也不需要知道那些线程中其实已经发生了 goroutine 调度。

g & m

在 Golang-nuts 上有一篇贴子 [Understanding of runtime goroutine struct G & M][1]. 在这篇贴子里大家讨论了 runtime 中的 gm 结构体,这两个结构体于与 goroutine 的实现相关,简单的来说:

一个 g 代表一个 goroutine,一个 m 代表一个系统线程

g 运行在 m 中, m 中有多个 g 等待执行。 当运行着的 g 堵塞时,该 m 中剩下的 g 会自动转移到没有被堵塞的 m 中, 这样其余的 goroutine 就不会被堵塞了。当然这一切对程序员是不可见的。

p

在 golang-nuts 中并没有提及另外一个重要的结构体 p, 在 [morsmachine][8] 的一篇博文中,他说 p 代表了处理器。 他还说一个 g 要被运行必须要有 p,整个运行结构如下图所示。

出自 [8]

每个 p 都有一个本地的 g 队列。 m + p + g 才是一个运行着的 goroutine.

Gosched

runtime.Gosched 用于让出被执行的权利,使得其他等待中的 goroutine 有机会得以执行,但这并不会终止 Gosched 的 caller。

明了 Gosched 后,我们再看看它是怎么实现的。下面的 mcall(gosched_m) 有点蹊跷, mcall 怎么只有一个函数签名,它的函数体在哪里? gosched_m 需要一个参数 *g, 但又它在哪里呢?

func Gosched() {
	mcall(gosched_m)
}

func mcall(fn func(*g))

// Gosched continuation on g0.
func gosched_m(gp *g) {
	if trace.enabled {
		traceGoSched()
	}
	goschedImpl(gp)
}

... ...

Read more →

博客搬家了

没错,这又是一篇无聊的“搬家”博文(等等,为什么是“又”)。但这次有点特殊,并不是博客托管方的改变,而是博客生成器的变动。

本博正式从 [Hexo][1] 搬到 [Hugo][2] 了。

最初促使我抛弃 Hexo 的原因是 Hexo 的文件监视有点问题(至少在我电脑上),开启 hexo 后,文件改动 2-8 次后,hexo 就再也无法观察到文件的变动了。还别说这是个小 feature,它对博文发表最后的微调阶段有很大的影响。

在多次尝试从外部解决失败后,其中包括重启,升级 Hexo 等,正好看到 golang 也有[博客生成器][2],一拍脑袋,决定搬家了。

... ...

Read more →

Introducing Slender-Next

Slender-Next

Yet another sample theme for Hugo with base16 color schemes.

Based on slender, inspired by hexo-theme-next

Screenshot

screenshot

Features

  • Responsive
  • Pagination
  • base16 color schemes
  • Code/syntax highlighting with highlight.js 9.1.0
  • Proper meta tags for SEO
  • Optimized for China
  • Google Analytics And Baidu Tongji integration
  • Disqus And Duoshuo integration
  • MathJax support
  • Table of Content
  • Tags + Archive

... ...

Read more →

Debian Packaging 教程

新手之痛

说实话把自己的程序打包成 deb, 对新手来说,真的不容易。网上的文档都太烦,烦到看不懂,涉及到很多工具,比如这句命令:

sudo apt-get install build-essential devscripts ubuntu-dev-tools debhelper dh-make diff patch cdbs quilt gnupg fakeroot lintian pbuilder piuparts

这些文档写得也是如何打包别人的源码,但关键别人的 debian 配置文件多,每个文件的代码也都很多,还不如看文档。还有的项目更过分,连 debian 的配置文件都不给出。(迷之眼泪 (╥﹏╥)

有志者事竟成,我倒腾了几天终于有成功了,打包出了 deb,Launchpad 上也有了我的 PPA。这儿记录一下,防止自己忘记,也方便新人入门。

没有严格遵守 Debian 社区打包的步骤,这记录的是一个 quick and dirty way not the Debian way!这是大概的过程:

  1. 创建 GPG: 用于给 deb 签名
  2. 打包 DEB: 有点麻烦,规矩多,步骤多
  3. 上传 Launchpad: 添加到 PPA,以后安装就方便了

创建 GPG

阮一峰有一篇非常棒的 [GPG入门教程],里面涵盖了新手上手 GPG 所需的基本步骤。

我在这补充一下,他的文章中上传公钥使用的是 hkp://subkeys.pgp.net,我这试了几次都出现了连接错误。所以,我推荐 hkp://keyserver.ubuntu.com,使用它,不仅是因为连得上,还因为在 Launchpad 创建 PPA 也要用它。

创建 PPA

摘自 [How do I create a PPA?]

创建 Launchpad 帐号

激活 PPA

用 GPG 签约 the Ubuntu code of conduct

... ...

Read more →