go在设计的时候,就有针对并行的语法 —-channel 和goroutine
前者 可以很方便的进行消息和数据传递,在取数据和拿数据的时候可以不用关心底层实现,用 <- 进行赋值
这里必须加time.sleep 不然程序很快就结束,read 和 write 甚至都来不及运行。这里和linux 线程编程很像。现在还不知道有没有更好的方式(貌似看到有人写过 ,用某种方式通知main 结束)
package main
import (
"fmt"
"time"
"math/rand"
)
var ch chan int
func read() {
for{
c := <- ch
fmt.Println("i read ", c)
}
}
func write(){
for{
c := 0
i := rand.Int()%10
c += i
fmt.Println("i write",c)
ch <- c
}
}
func main(){
ch = make(chan int ,4)
go write()
go read()
time.Sleep(1000000)
}
wordcount 代码实现,知道hadoop的都应该知道这个,并行计算,那么在go 里面也很好实现:
main: readfile : 读取文件,进行任务分发 ,分发到三个相同的计算线程 ,只是通过不同的chan来 传递任务(这里的任务就是统计一行字符的每个单词出现的次数)
compute : 计算线程 ,将结果发送到 一个全局的chan中
redeuce : 从全局的chan 中取出结果,合并的最终的结果中 。
感觉自己写的程序还不是很规范,思路很多都局限于之前写C的思路。这里
package main
/*
#include <stdio.h>
*/
import (
"os"
"fmt"
"bufio"
"time"
"strings"
"C"
"runtime"
)
var str1 chan string
var str2 chan string
var str3 chan string
var keyWordmap chan map[string]int
var result map[string]int
func wordCount(s string) map[string]int {
m:= make(map[string]int)
words:=strings.Fields(s)
for i:=0;i<len(words);i++ {
m[words[i]] += 1
}
return m
}
func compute(num int ){
for {
var str string
if num == 1{
str = <- str1
}else if num == 2{
str = <- str2
}else if num == 3{
str =<- str3
}else {
return
}
m := wordCount(str)
keyWordmap <- m
//fmt.Printf("%v#",m)
}
}
func reduce (){
for {
m := <- keyWordMap
for key,value := range m{
fmt.Println(key,value)
result[key] += value
}
}
}
func readfile() {
//var content [100]byte
fp ,_ := os.Open("wc.txt")
br := bufio.NewReader(fp)
defer fp.Close()
for i:= 1; ; i++ {
line,err := br.ReadString('\n')
if err != nil{
//return -1
break
}
//fmt.Println(line)
//str1 <- line
if i %3 == 0{
str3 <- line
}else if i % 3 == 1{
str1 <- line
}else if i %3 == 2{
str2 <- line
}
}
/*
//t.Println(string(content[:]))
//mystr := string(content[:])
//array := strings.Split(mystr,"/r/n")
//fmt.Println(array[:])
*/
}
func main(){
runtime.GOMAXPROCS(2)
str1 = make(chan string ,3)
str2 = make(chan string ,3)
str3 = make(chan string ,3)
keyWordmap = make(chan map[string]int ,5)
result = make(map[string]int)
time.Sleep(1000000)
go readfile()
//time.Sleep(100000000)
go reduce()
go compute(1)
go compute(2)
go compute(3)
time.Sleep(10000000000)
/*
for{
time.Sleep(10000000)//10ms
fmt.Printf("%v#",result)
}
*/
defer fmt.Printf("the end result :%v#",result)
}
tips: