眺めて覚えるGo言語 その15 並列処理

#マルチスレッドのCPUを使っているのにプログラム1個分しか走らないと寂しい。
##Go言語でマルチスレッドプログラミング!
###まず眺める

```ex3a.go
package main

import ("fmt";"reflect";"os";"log";"strings";"strconv";"time";)

func main(){
	tmnow()	
	defer tmnow()
	done:=make(chan bool)
	var sx float64
	go func(){
		for i:=0;i<=2000000;i++{
			sx+=float64(i)
		}
		done<- true
	}()
	<-done
	fmt.Printf("sum= %10.0f\n",sx)
}
// ReadFileは、ファイル読み込み
func ReadFile(fn string) string{
	buf:=make([]byte,32768)
	f:=m2s(os.Open(fn)).(*os.File) //cast
	defer f.Close()
	f.Read(buf)
	return string(buf)

}
// m2sは、ずるいことツール
// m2s mult value return to single value
func m2s(x,err interface{}) interface{}{
	// fmt.Printf("Type:%t\n",reflect.TypeOf(x))
	if err != nil {
		log.Fatal(err)
	}
	return x
}
// printは、デバック時にずるするための関数
func print(a ...interface{}){
	fmt.Println(a)
}
// typofは、デイバック時にずるするための関数
func typeof(a interface{}){
	print(reflect.TypeOf(a))
}
// Int string to int デイバック時にずるするための関数
func Int(a string) int{
	i:=m2s(strconv.Atoi(a)).(int)
	return i
}
var st time.Time
// tmnow デイバック時にずるするための関数
func tmnow() {
	if st.IsZero()==true {
		st=time.Now()
	} else {
		w:=time.Now()
		sec:=w.Sub(st).Seconds()
		fmt.Println("実行時間",sec)
	}

}
// Split デイバック時にずるするための関数
func split(s string,sep string) []string {
	return strings.Split(s,sep)
}

```

## もう一つ眺める
スレッドの関数化する。

```ex3b.go

package main

import ("fmt";"reflect";"os";"log";"strings";"strconv";"time";)

func sigma(st,et int64,done chan float64){
	var s float64
	for i:=st;i<=et;i++{
		s+=float64(i)
	}
	done<-s
}
func main(){
	tmnow()	
	defer tmnow()
	done:=make(chan float64)
	go sigma(0,2000000,done)
	printf("sum= %10.0f\n",<-done)
}
// ReadFileは、ファイル読み込み
func ReadFile(fn string) string{
	buf:=make([]byte,32768)
	f:=m2s(os.Open(fn)).(*os.File) //cast
	defer f.Close()
	f.Read(buf)
	return string(buf)

}
// m2sは、ずるいことツール
// m2s mult value return to single value
func m2s(x,err interface{}) interface{}{
	// fmt.Printf("Type:%t\n",reflect.TypeOf(x))
	if err != nil {
		log.Fatal(err)
	}
	return x
}
// printは、デバック時にずるするための関数
func printf(f string,a ...interface{}){
	fmt.Printf(f,a)
}
// typofは、デイバック時にずるするための関数
func typeof(a interface{}){
	fmt.Println(reflect.TypeOf(a))
}
// Int string to int デイバック時にずるするための関数
func Int(a string) int{
	i:=m2s(strconv.Atoi(a)).(int)
	return i
}
var st time.Time
// tmnow デイバック時にずるするための関数
func tmnow() {
	if st.IsZero()==true {
		st=time.Now()
	} else {
		w:=time.Now()
		sec:=w.Sub(st).Seconds()
		fmt.Println("実行時間",sec)
	}

}
// Split デイバック時にずるするための関数
func split(s string,sep string) []string {
	return strings.Split(s,sep)
}
実行結果
>go run ex3b.go
sum= [2000001000000]
実行時間 0.0040071
```
doneに戻り値が来るのを眺める。
printf("sum= %10.0f\n",<-done)は、戻り値を待って表示する。


#select で待つ

```ex3c.go

package main

import ("fmt";"reflect";"os";"log";"strings";"strconv";"time";)

func sigma(st,et int64,done chan float64){
	var s float64
	for i:=st;i<=et;i++{
		s+=float64(i)
	}
	done<-s
}
func main(){
	tmnow()	
	defer tmnow()
	done0:=make(chan float64)
	done1:=make(chan float64)
	go sigma(      0,1000000,done0)
	go sigma(1000001,2000000,done1)	
	var mx float64
	for i := 0; i < 2; i++ {
        select {
        case d0 := <-done0:
			printf("done0 sum= %10.0f\n",d0)
			mx+=d0
        case d1 := <-done1:
			printf("done0 sum= %10.0f\n",d1)
			mx+=d1
		}
	}
	printf("finish sum= %10.0f\n",mx)
}
// ReadFileは、ファイル読み込み
func ReadFile(fn string) string{
	buf:=make([]byte,32768)
	f:=m2s(os.Open(fn)).(*os.File) //cast
	defer f.Close()
	f.Read(buf)
	return string(buf)

}
// m2sは、ずるいことツール
// m2s mult value return to single value
func m2s(x,err interface{}) interface{}{
	// fmt.Printf("Type:%t\n",reflect.TypeOf(x))
	if err != nil {
		log.Fatal(err)
	}
	return x
}
// printは、デバック時にずるするための関数
func printf(f string,a ...interface{}){
	fmt.Printf(f,a)
}
// typofは、デイバック時にずるするための関数
func typeof(a interface{}){
	fmt.Println(reflect.TypeOf(a))
}
// Int string to int デイバック時にずるするための関数
func Int(a string) int{
	i:=m2s(strconv.Atoi(a)).(int)
	return i
}
var st time.Time
// tmnow デイバック時にずるするための関数
func tmnow() {
	if st.IsZero()==true {
		st=time.Now()
	} else {
		w:=time.Now()
		sec:=w.Sub(st).Seconds()
		fmt.Println("実行時間",sec)
	}

}
// Split デイバック時にずるするための関数
func split(s string,sep string) []string {
	return strings.Split(s,sep)
}

実行結果

go run ex3c.go
done0 sum= [1500000500000]
done0 sum= [500000500000]
finish sum= [2000001000000]
実行時間 0.0030031

```