MIT 6.824 - Lab 1 (2): Go buildmode

Lab 1 中遇到的第一个命令是 go build -race -buildmode=plugin ../mrapps/wc.go,其中 -buildmode=plugin 表示以插件的形式打包源文件,这里的 wc.go 是用户实现的 mapreduce 方法,这体现了面向接口编程的思想,只要用户编写的 mapreduce 方法遵循统一的签名,则可以在不重新编译 MapReduce 框架代码的情况下,实时替换运行不同的用户应用。

假设有个 sum.go 文件,里面只有一个 Sum 方法:

1
2
3
4
5
package main

func Sum(a int, b int) int {
return a + b
}

sum.go 以插件形式编译:

1
go build -buildmode=plugin sum.go

会生成一个 sum.so 文件。

接着,在 main.go 中就可以通过 plugin.Open 读取 sum.so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
"fmt"
"log"
"plugin"
)

func main() {
fileName := "sum.so"
p, err := plugin.Open(fileName)

if err != nil {
log.Fatalf("cannot load plugin %v", fileName)
}

sumSymbol, err := p.Lookup("Sum")

if err != nil {
log.Fatalf("cannot find Map in %v", fileName)
}

sum := sumSymbol.(func(int, int) int)

fmt.Println("1 + 2 is", sum(1, 2))
}

然后通过 Lookup 根据方法名找到 Sum 方法,按照指定方法签名转换后即可进行调用。而如果需要换一个 Sum 的实现,则无需重新编译 main.go

参考: