Golang基礎_11-並行処理の同時実行

注意事項

  • ゴルーチン唯一の公式スーパースレッドプール
  • 高い同時実行:小さなメモリ、すぐに破壊を作成します
  • 開発者が使いやすい巨大な利便性を与えることなく、ゴルーチンの言語レベル
  • 並行して、並列動作を直接マルチコア・マルチスレッドを実装されているより複雑な、並行処理は、スイッチングタイムスライス「同時」操作することによって達成されます
  • ゴルーチン通信のための共有メモリの代わりに通信(チャネル)メモリで共有追求

    チャネル

  • ゴルーチンチャネルは主に同期をブロック、ブリッジであります
  • メイクによって作成され、近い閉じます
  • チャネルパラメータは、自分の操作に直接渡すことができ、参照型、であること

func main(){
    c := make(chan bool)
    go func(){
        fmt.Println("GO GO GO")
        c <- true
    }()
    <- c
}
/*
> Output:
command-line-arguments
GO GO GO
*/
  • 連続的に作動するチャンネルを反復する範囲のために使用することができます
  • 反復時間は、私が覚えておく必要があります閉じ近いどこか(c)を呼び出すために、デッドロックを避けるために、
func main(){
    c := make(chan bool)
    go func(){
        fmt.Println("GO GO GO")
        c <- true
        close(c)
    }()
    for v := range c {
    //程序运行到这,一直等待着c会有值
        fmt.Println(v)
    }
}
  • 一方向又は双方向チャネルを提供することができます
  • あなたはキャッシュサイズを設定することができ、ブロッキングが充填されていない前に発生しません
    を参照して、キャッシュに:言語_行く同時論文は、
    ここで説明する絵を書きます
    キャッシュが非同期である必要があり、非ブロックキャッシュが同期されている
    最初のキャッシュを入れた
    最初のキャッシュを取らず

    障害や問題の欠如..whatever

func main(){
    runtime.GOMAXPROCS(runtime.NumCPU())
    c := make(chan bool)
    for i:=0; i<10 ; i++ {
        go Go(c,i)
    }
    <-c
}
func Go(c chan bool, index int){
    a := 1
    for i:=0;i<1000000;i++{
        a += i
    }
    fmt.Println(index,a)

    if index==9 {
        c <- true
    }
}
/*
> Output:
command-line-arguments
1 499999500001
0 499999500001
2 499999500001
9 499999500001
*/

上記の出力は神聖である満たしていない場合、大臣は、次の2つの計画を与えました

計画:チャンネルプラスバッファへ

func main(){
    runtime.GOMAXPROCS(runtime.NumCPU())
    c := make(chan bool,10)
    for i:=0; i<10; i++ {
        go Go(c,i)
    }
    for i:=0;i<10;i++{
        <- c
    }
}
func Go(c chan bool, index int){
    a := 1
    for i:=0;i<1000000;i++{
        a += i
    }
    fmt.Println(index,a)

    c <- true
}
/*
> Output:
command-line-arguments
2 499999500001
1 499999500001
9 499999500001
0 499999500001
6 499999500001
3 499999500001
5 499999500001
7 499999500001
8 499999500001
4 499999500001
*/

トリック2:同期パケットを導入

package main
import (
    "fmt"
    "runtime"
    "sync"
)
func main(){
    //(runtime包是goroutine的调度器),runtime.GOMAXPROCE设置允许同时最多使用多少个核
    runtime.GOMAXPROCS(runtime.NumCPU())
    wg := sync.WaitGroup{}
    for i:=0; i<10; i++ {
        //waitgroup作为结构,使用&进行地址传递
        go Go(&wg,i)
    }
    wg.Wait()
}
func Go(wg *sync.WaitGroup, index int){
    a := 1
    for i:=0;i<1000000;i++{
        a += i
    }
    fmt.Println(index,a)

    wg.Done()
}

選択

  • 特にチャンネルに設計された構造
func main(){
    c1,c2 := make(chan int),make(chan string)
    o := make(chan bool)
    go func(){
        for{
            select{
            case v,ok := <-c1:
                if !ok{
                    o <- true
                    break
                }
                fmt.Println("c1",v)
            case v,ok := <-c2:
                if !ok{
                    o <- true
                    break
                }
                fmt.Println("c2",v)
            }
        }
    }()
    c1 <- 1
    c2 <- "hi"
    c1 <- 3
    c2 <- "lel"

    close(c1)
    //close(c2)
    for i:=0;i<2;i++{
        <- o
    }
}
//没办法同时记录两个select的执行次数
  • あなたは、一の以上のチャネルの送受信を処理することができます。
func main(){
    c := make(chan int)
    go func(){
        i := 0
        for v:= range c {
            i ++
            fmt.Println(v)
            if i>10{
                break
            }
        }
    }()

    for {
        select {
        case c <- 0:
        case c <- 1:
        }
    }
}
//运行结果很鬼畜,,
  • 利用可能な複数の処理と同時に、ランダムな順序チャネル
  • 主な機能をブロックするのに利用可能な空の選択
  • あなたはタイムアウトを設定することができます
package main
import (
    "fmt"
    "time"
)
func main(){
    c := make(chan bool)
    select {
    case v := <- c:
        fmt.Println(v)
    case <-time.After(3*time.Second):
        fmt.Println("timeout")
    }
}
//time.After()返回一个time型的chan

例:メッセージ送受信数はゴルーチンによって達成

package main

import (
    "fmt"
)

var cc chan string

func main() {
    cc = make(chan string)

    go Go()
    for i := 0; i < 5; i++ {
        cc <- fmt.Sprintf("From main:hello, #%d", i)
        fmt.Println(<-cc)
    }

}
func Go() {
    for i := 0; ; i++ {
        fmt.Println("djd", <-cc)
        cc <- fmt.Sprintf("From Go:hi,#%d", i)
    }
}
/*
    djd From main:hello, #0
    From Go:hi,#0
    djd From main:hello, #1
    From Go:hi,#1
    djd From main:hello, #2
    From Go:hi,#2
    djd From main:hello, #3
    From Go:hi,#3
    djd From main:hello, #4
    From Go:hi,#4
*/

おすすめ

転載: www.cnblogs.com/leafs99/p/golang_basic_11.html