Golang sync包源码剖析

Golang在标准库中提供了一些并发编程所需要的基本工具,包括同步机制、原子操作、对象池等,这些工具基本都包含在sync包中,本文从源码入手简单分析一下各个工具的实现机制。

原子操作

Golang的原子操作函数全部包含在了sync/atomic中。sync包中其他许多工具的实现都依赖于原子操作,所以先来看一下原子操作的实现。

原子操作的实现全部在asm_xxx.s文件中,使用汇编写成。以amd64平台的cas操作为例,它的源码如下:

1
2
3
4
5
6
7
8
9
10
11
TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
MOVQ addr+0(FP), BP
MOVL old+8(FP), AX
MOVL new+12(FP), CX
// 载入参数
LOCK
CMPXCHGL CX, 0(BP)
// 使用LOCK前缀完成交换操作
SETEQ swapped+16(FP)
//设置返回值
RET

可见cas操作是通过对修改命令加LOCK前缀实现的,LOCK前缀可以保证对CPU缓存的操作是排他的。

Rust初体验

Rust 作为一个新兴语言经常被拿来跟 Golang 比较,我又是个 Golang 爱好者,所以从大概去年这个时候开始关注 Rust。不过因为 Rust 的语法比较复杂,所以始终也没有系统地过一遍。恰好最近 o’reilly 家非常良心地出了一本 Rust 的免费电子书,叫《Why Rust?》,只有62页,我就抽周五无聊的电路实验闲暇把它看了一遍,有些比较感兴趣的部分又看了看官方的《The Rust Book》,算是对 Rust 有了一个系统的了解,就随手写一下我的感受。

本文主要是几个我比较关心的方面 Rust 与 Golang 的比较。毕竟我没怎么用过 Rust,所以这篇文章也许有偏颇之处,欢迎理性讨论。

GeneDock基于Docker的部署运维实践

写在前面:这是我在GeneDock实习期间做的主要的事情,所以这篇文章同时发布在了公司的技术博客上。实习这段时间我学到了很多的东西,非常感谢各位同事的指导和帮助。

(本文由GeneDock公司实习工程师胡英谦撰写,转载请保留作者信息和原文链接)

如何基于Docker容器技术,构建一个自动化、易用、高可用的运维部署系统。本文希望分享GeneDock的经验和教训。

使用Cgo的一点总结

今天想给一个C库写一个Golang binding,就查了一下cgo的使用,也遇到了一些坑。

cgo的基本使用

想在Go代码中使用C语言必须在代码开头注释中写,然后再紧接着的下一行写import "C",这样就算是导入完成了。这个”C”不是一个真正的包,而是一个类似于命名空间的东西,所有能调用的C的变量、函数都包含在里面。
举个最简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main
// #include <stdio.h>
// #include <stdlib.h>
/*
void print(char *str) {
printf("%s\n", str);
}
*/

import "C"
import "unsafe"

func main() {
s := "hello"
cs := C.CString(s)
defer C.free(unsafe.Pointer(cs))
C.print(cs)
}

[译]Go和Rust:两个新型编程语言的未来道路

原文地址,如有侵权请联系我,我会立刻删除。

没有什么事情比讨论一门新语言更能令程序员感到兴奋或固执的了。现在,程序员们可以欣赏两颗冉冉升起的明日之星:GoRust,两者有着相似的灵感,但是发展动机和目标却有着本质差别。
这两门语言都有着一流的出身,都是在现代IT界的巨头赞助下创造出来的。Go是由Google的Rob Pike和Ken Thompson创造;Rust则是Mozilla的Graydon Hoare的劳动成果。两者都是从一个实验性项目起步,然而都快速地生长成为了成熟的开发工具。

关于goroutine调度时机的一点探究

最近遇到了一点goroutine调度的问题,就去搜了一下在什么情况下会触发goroutine的调度,可惜搜到的资料不是语焉不详就是Go版本太老。于是我参考这些资料自己写了几段代码试了一下。

代码测试环境:

  • Go 1.4.2
  • Ubuntu 15.04

[翻译]用Go语言编写web应用

原文来自官网,如有侵权请联系我,我会立刻删除。

介绍

本文中包含的内容有:

  • 通过载入和保存方法创建一个数据结构
  • 使用net/http包来创建web应用
  • 使用html/template包来使用HTML模板
  • 使用regexp包来验证用户输入
  • 使用闭包
    假定你已有的知识:
  • 编程经验
  • 了解基本的web技术
  • 一些UNIX/DOS命令行知识

[翻译]Docker Compose工具快速入门

Docker Compose

译者注:原文地址,本译文仅供学习参考,如有侵权请立即联系我,我会立即删除。

Compose是一个用于在Docker上定义并运行复杂应用的工具。通过Compose,你可以很容易地使用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。

在开发环境、临时服务器、CI中使用Compose是非常合适的。但是,我们目前不建议你在生产环境中使用。

使用Compose需要三个基本步骤。

[翻译]Spark编程指南(Python版)

Spark编程指南

译者说在前面:最近在学习Spark相关的知识,在网上没有找到比较详细的中文教程,只找到了官网的教程。出于自己学习同时也造福其他初学者的目的,把这篇指南翻译成了中文,笔者水平有限,文章中难免有许多谬误,请高手不吝赐教。
本文翻译自Spark Programming Guide,由于笔者比较喜欢Python,在日常中使用也比较多,所以只翻译了Python部分,不过Java和Scala大同小异。

概述

从高层次上来看,每一个Spark应用都包含一个驱动程序,用于执行用户的main函数以及在集群上运行各种并行操作。Spark提供的主要抽象是弹性分布式数据集(RDD),这是一个包含诸多元素、被划分到不同节点上进行并行处理的数据集合。RDD通过打开HDFS(或其他hadoop支持的文件系统)上的一个文件、在驱动程序中打开一个已有的Scala集合或由其他RDD转换操作得到。用户可以要求Spark将RDD持久化到内存中,这样就可以有效地在并行操作中复用。另外,在节点发生错误时RDD可以自动恢复。

网络编程一些零碎知识点

阻塞网络IO也是有陷阱的:类似死锁。比如服务器和客户端都阻塞到了send。
本质原因是内核缓冲区大小有限。在发个大的包的时候服务器可能会一次收一部分(buf的大小),然后直接发送,但是这时客户端还阻塞在send上,于是就完全被阻塞住了。简单的解决办法就是尽量不要依赖内核缓冲区,自己做一个缓冲区,一个包要一次收完。