golangプレミアムセクション

11005 ワード

一、golangのOOP(orient object programming)
関数宣言時に、その名前の前に変数を置くのがメソッドです.この追加のパラメータは、このタイプに関数を追加します.すなわち、このタイプの排他的な方法を定義することに相当します.(c++でメンバー関数と呼ぶ)
二、GoroutineとChannels
golangでは、各同時実行ユニットをgoroutineと呼ぶ.channelはそれらの間の通信メカニズムであり、1つのgoroutineがchannelを通じて別のgoroutineにメッセージを送信することができる.各チャネルには特殊なタイプがあることに注意してください.
  ch := make(chan int)
close(ch)/channelを閉じる
2.1 buffer channelなし
    ch := make(chan int)  or   ch := make(chan int , 0)
キャッシュレスチャネルに基づく送信操作は、送信者goroutineがブロックされ、別のgoroutineが同じチャネル上で受信操作を実行するまで、送信された値がチャネルを介して正常に送信された後、2つのgoroutineは後続の文を実行し続けることができる.逆に、受信操作が先に発生すると、受信者goroutineもブロックされ、
別のgoroutineが同じChannels上で送信操作を実行します.
キャッシュレスチャネルによる送受信操作により、2つのgoroutineが同期操作を1回行うことになります.このため、キャッシュレスチャネルは同期チャネルとも呼ばれることがある.キャッシュレスチャネルを介してデータが送信されると、受信者が受信したデータは、送信者goroutineを起動する前に発生する.
2.2一方向のチャンネル
タイプchan
1  12 // out    channel
2  13 // in   channel
3  14 func squares(out chanin chan int) {
4  15     for v := range in {
5  16         out  v
6  17     }
7  18     close(out)
8  19 }

2.3 buffer付きchannel
    ch = make(chan string, 3)
キャッシュチャネルへの送信は内部キャッシュキューの末尾に要素を挿入し,受信はキューのヘッダから要素を削除する.内部キャッシュキューがいっぱいである場合、送信操作は、別のgoroutineが受信操作を実行して新しいキュー空間が解放されるまでブロックされます.逆にchannelが空の場合、受信操作は別の操作があるまでブロックされます.
goroutineは送信操作を実行してキューに要素を挿入します.
取得channelの容量:cap(ch)取得channelデータの長さ:len(ch)
三、select多重
 1 package main
 2 
 3 import (
 4     "fmt"
 5     //"time"
 6 )
 7 
 8 /*
 9 select {
10 case ch1:
11     // ...
12 case ch2:
13     // ...
14 case ch3:
15     // ...
16 default:
17     // ...
18 }
19 */
20 
21 func main() {
22     j := make(chan int, 1)
23     //tick := time.Tick(1 * time.Second)
24     for down := 10; down > 0; down-- {
25         fmt.Println("down to here")
26         select {
27         case x := j:
28             fmt.Println(x)
29         case j  down:
30             fmt.Println("put to j")
31         }   
32     }   
33 }

一、同時
一般的に,2つのgoroutineイベントxとyの実行順序に位置し,xがyの前か後か同時に発生するかは判断できない.あるイベントが別のイベントの前後で発生していることを明確に確認できない場合は,xとyの2つのイベントが同時であることを示す.
競争を避けるにはどうすればいいですか?
他のgoroutineは変数に直接アクセスできないため、指定したgoroutineリクエストに送信するために1つのchannelしか使用できません.これがGoの口癖「共有データで通信するのではなく、通信でデータを共有する」です.指定された変数に対してcahnnelを介して要求を提供する
のgoroutineをこの変数のモニタリング(monitor)goroutineと言います.
二、反発
相互反発プロトタイプ実装:
 1 var (
 2     sema    = make(chan struct{}, 1)
 3     balance int 
 4 )
 5 
 6 func Add(amount int) {
 7     sema  struct{}{}
 8     balance = balance + amount
 9     sema
10 }
11 
12 func Get() int {
13     sema  struct{}{}
14     b := balance
15     sema
16 }
17 
18 import "sync"
19 var (
20     mu sync.Mutex
21     balance int
22 )          
23 func Add(amount int){
24     mu.Lock()
25     balance = balance + amount 
26     mu.Unlock()
27 }  
28 
29 func Get() int {
30     mu.Lock()
31     b := balance
32     mu.Unlock()
33 }

 
   func Get() int {
    mu.Lock()
    defer mu.Unlock()
    b := balance 
    return b
  }
2.1読み書きロック
   var rwmu sync.RWMutex----多度少写に用いる
   rwmu.Rlock()/rwmu.RUnlock()----リードロック、この場合はリード操作のみ
   rwmu.Lock()/rwmu.Unlock()----読み書きロック
 2.2 sync.Once初期化
 1 /*
 2  sync.Once。      ,
 3                mutex   boolean                ;
 4         boolean          。 Do                  
 5  6 */
 7 var loadIconsOnce sync.Once
 8 var icons map[string]int
 9 func loadIcons() {
10      icons["first"] = 1
11      icons["second"] = 2
12      icons["thrid"]     = 3   
13 }
14 
15 func Icon(name string) int {
16     loadIconsOnce.Do(loadIcons)
17     return icons[name]
18 }

   2.3 sync.WaitGroup
まずWaitGroupの用途について説明します.すべてのgoroutineの実行が完了するまで待つことができ、すべてのgoroutineの実行が完了するまでメインスレッドの実行をブロックすることができます.ここで、彼らの実行結果には順序がなく、スケジューラは複数のgoroutine実行順序を保証することができず、プロセスが終了するのを待つことはありません.
WaitGroupには、Add(delta int)、Done()、Wait()の3つの方法があります.この3つの方法の役割を簡単に説明します.
Add:goroutineを待つ数を追加または減らす
Done:Add(-1)に相当
Wait:すべてのWaitGroup数が0になるまでブロックを実行
次のようになります.
golangでの同期はsync.WaitGroupが実現する.WaitGroupの機能:キューにタスクをずっと追加することができ、タスクが完了するとキューから削除することができ、キューのタスクが完全に完了していない場合は、Wait()関数によってブロックすることができ、すべてのキュータスクが完了するまでプログラムが継続することを防止する.
WaitGroupの特徴はWait()がキュー内のすべてのタスクが完了するまでブロックを解除するために使用できることであり、sleepが一定の時間待つ必要はありません.しかし、固定されたgoroutineの数を指定できないという欠点があります.channelを使用してこの問題を解決する可能性があります.