0
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-01-31

マルチスレッドの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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0