go語言 -並行程序 wordcount

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:

  • godoc -http=:8000  運行本地的文檔,通過web 的方式進行訪問

參考:

  1. Go Lang介紹
原始博客地址:http://www.fuxiang90.com/2012/08/go%E8%AF%AD%E8%A8%80-%E5%B9%B6%E8%A1%8C%E7%A8%8B%E5%BA%8F/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章