通过上一篇转载的文章 "Yesterday Once More ---再次遇到Go语言",可以搭建Go语言开发环境了。
现在开始Go语言(Golang)程序开发, here we Go.
Example 1. 最简单的程序Let's Go:
package main // There must be a so-called main package for a Go EXE.
import "fmt" // fmt is a package including Print
func main(){ //The entry of a Go EXE
fmt.Print("Hello,Let's Go") //Main program context
}
程序代码非常简单,任何有编程功底的人都可以看懂。
在Eclipse中Run即可在Console中看到打印结果:
Hello,Let's Go
Example 2. 并行程序(多协程,可以简单地理解成多线程程序)
(*注1,协程者,轻量级线程也,因其轻量级,系统中的协程可以百万计)。具体实现此处不细表。
*注2,紫色颜色处代码表示本例子是改自上面的例子,同时紫色本身代码表示修改/添加的代码。这样更方便读者阅读。)
这基本上是一个Go语言中并发程序的雏形;但是大家其实可能已经看出,主进程在创建协程后即退出,因此可能该协程根本没有机会执行。
package main // There must be a so-called main package for a Go EXE.
import "fmt" // fmt is a package including Print
func Coroutine(){ //Coroutine function
fmt.Println("go")
}
func main(){ //The entry of a Go EXE
//Main program context
fmt.Println("Hello,Let's ...");
go Coroutine();
}
Example 3. 引入同步机制,实现真正的并行程序
Golang中用channel实现协程间通信, 可以用sync包中的Mutex, RWMutex来实现协程间同步以及资源共享,channel也可以用来协程间同步。
Golang中的channel就类似于linux中的管道,原理一样。
package main // There must be a so-called main package for a Go EXE.
import "fmt" // fmt is a package including Print
func Coroutine(ch chan int, i int ){ //Coroutine function
fmt.Println("go", i);
ch <- i; //write a int value to chan
}
func main(){ //The entry of a Go EXE
//Main program context
fmt.Println("Hello,Let's ...");
chs := make([]chan int, 10); //make an array containning 10 chan
for i := 0; i < 10; i++{ //
chs[i] = make(chan int); //create a chan value
go Coroutine(chs[i], i); //run a coroutine
}
//For the main process, read value from the chan array
for _,ch := range(chs){ //loop the array
//read value from each chan if there's a value;
//otherwise, it is locked.
c := <- ch;
fmt.Println("Main Process gets from Coroutine:", c)
}
}
(*Go程序每句结束不必用分号;但是我个人习惯还是加了个分号。)
此程序创建了10个协程,主程序与协程之间通信以及同步。
输出:
Hello,Let's ...
go 0
go 1
go 2
go 3
go 4
go 5
go 6
go 7
go 8
go 9
Main Process gets from Coroutine: 0
Main Process gets from Coroutine: 1
Main Process gets from Coroutine: 2
Main Process gets from Coroutine: 3
Main Process gets from Coroutine: 4
Main Process gets from Coroutine: 5
Main Process gets from Coroutine: 6
Main Process gets from Coroutine: 7
Main Process gets from Coroutine: 8
Main Process gets from Coroutine: 9
Example 4. 加点高级技巧:使用匿名函数+多核支持
(*注,匿名函数与是否多核完全没有联系,只是为了在一个例子同时用这个2个技巧)
package main // There must be a so-called main package for a Go EXE.
import "fmt" // fmt is a package including Print
import "runtime"
func main(){ //The entry of a Go EXE
//Main program context
fmt.Println("Hello,Let's ...");
chs := make([]chan int, 10); //make an array containning 10 chan
runtime.GOMAXPROCS(10);//Make the coroutines running in 10 CPUs
for i := 0; i < 10; i++{ //
chs[i] = make(chan int); //create a chan value
go func(ch chan int, i int){//Use anonymous function instead
fmt.Println("go", i);
ch <- i; //write a int value to chan
}(chs[i],i); //pass the value into funciton
}
//For the main process, read value from the chan array
for _,ch := range(chs){ //loop the array
//read value from each chan if there's a value;
//otherwise, it is locked.
c := <- ch;
fmt.Println("Main Process gets from Coroutine:", c)
}
}
这样,我们就实现了一个完整的在多核系统上运行的并行程序。
此例在我的系统上(Intel Core 2 Duo) 的输出结果是:
Hello,Let's ...
go 0
go 4
go 5
go 6
go 7
Main Process gets from Coroutine: 0
go 2
go 8
go 9
go 1
Main Process gets from Coroutine: 1
Main Process gets from Coroutine: 2
go 3
Main Process gets from Coroutine: 3
Main Process gets from Coroutine: 4
Main Process gets from Coroutine: 5
Main Process gets from Coroutine: 6
Main Process gets from Coroutine: 7
Main Process gets from Coroutine: 8
Main Process gets from Coroutine: 9
Example 5. 做一个最简单的网站, Let's Go!
Webserver监听8080端口,收到客户端的yes的时候,做出回答。
package main // There must be a so-called main package for a Go EXE.
import( "fmt";"io";"log";"net/http")
func mainHandler(w http.ResponseWriter, r *http.Request){
io.WriteString(w,"Let's Go");
}
func main(){
http.HandleFunc("/yes", mainHandler);
fmt.Print("Sever is ready, shall we go?");
err := http.ListenAndServe(":8080",nil);
if err != nil{
log.Fatal("ListenAndServe:",err.Error());
}
}
程序可以在Eclipse中执行,也可以在命令行中执行,如下图。
客户端是用IE浏览器访问http://localhost:8080,并写消息"yes"到8080端口。
(*注,我遇到问题是我的杀毒软件一直阻挡我的main程序,这种情况下,需要暂时关闭该保护)
第一部分就到此为止;用意是用鲜明的例子激起大家(包括我自己)对这门语言的好奇或者喜爱。
参考文献
1. golang.org
2. 《Go语言编程》徐世伟 吕桂华等编著,人民邮电出版社