CSPモデルを使用したGo言語の特性


💡 CSP : Communicating Sequential Processes
Goを活用するには,Go処理の同時性を知る方法が必要である.
同期は、1つまたは複数のタスクを同時に行うことを意味し、特にGo上の同期はGoの大きな利点である.Goにおける同期性はCSPモデルに基づく.CSPは同期システム間で起こるインタラクションを記述する基本モデルの一つである.(ex.actitor、stmなど)
既存のプログラミング言語では、コードを同時に実行する場合、スレッドとスレッド間のデータ構造、変数、メモリなどを把握し、Mutex、Semapoirなどの同期オブジェクトを利用してリソースを管理する必要があります.したがって、2つ以上のスレッドが1つの共有リソースに同時にアクセスすることはできません.このような様子は裸のコミュニケーションと形容され、ご存知のように試合状態、記憶管理、未知の例外、死亡などを引き起こす.
そこで,上記の副作用を排除するために,Goは他のコミュニケーションを基本モードとする.共有メモリ変数をロックするのではなく、変数に格納されている値を送信(通信)します.最終的に、上記モデルの基本的な動作は、データを送信するスレッドと、データを受信する(到着を待つ)スレッドである.
安定した状態は、sendスレッドおよびrecvスレッドに依存し、送信が完了するまで他の挙動は生じない.これは試合状態などの問題が発生する機会がないことを意味する.すなわち、あるスレッドが動作を完了するまで、別のスレッド実行は作成されません.すなわち,この順序通信は基本モードである.
Goは複数の機能をサポートし、これらの順序通信動作を実現します.重要なのは、ライブラリレベルのサポートではなく、言語レベルのサポートです.buffered channelがサポートされています.これは、伝送が完了する間、スレッド間でいずれかまたはsyncを必要としないことを意味します.逆に、2つのThreedの間で予め定められたメンバーを操作する場合、sync/lockを選択することができる.
Goによる同期符号化には、goroutineおよびchannelを使用することができる.goroutineは、上述したスレッド概念を提供し、実際にはスレッドではなく、同じアドレス空間で他のgoroutineと同時に動作可能な機能を提供する.goroutineは、オペレーティングシステムのスレッドと一致せず、多重であるため、論理スレッドまたは仮想スレッドとも呼ばれる.すべての同期とメモリ管理は基本的にGo言語によって実行されます.goroutineを起動するには、任意の関数でgoキーを使用します.
package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 10; i++ {
        fmt.Println(s, "***", i)
    }
}

func main() {
    // 함수를 동기적으로 실행
    say("Sync")

    // 함수를 비동기적으로 실행
    go say("Async1")
    go say("Async2")
    go say("Async3")

    // 3초 대기
    time.Sleep(time.Second * 3)
}
goチャンネルはGoが同期を実現するもう一つの核心概念である.CSPで強調した通信の役割を担っているからだ.すなわち、goチャネルはgoroutine間でデータを伝達する役割を果たし、チャネルは「make()」関数で生成することができる.チャネルを介してデータを送信および受信する場合は、チャネル演算子<-を使用します.goroutineは、チャネルに値を次のように割り当てます.
package main
 
func main() {
  // 정수형 채널을 생성한다 
  ch := make(chan int)
 
  go func() {
    ch <- 123   //채널에 123을 보낸다
  }()
 
  var i int
  i = <- ch  // 채널로부터 123을 받는다
  println(i)
}
goチャンネルには、UnbufferedチャンネルとBufferedチャンネルの2種類があります.Unbufferedチャネルは、受信者がデータを受信するまで、送信者によってデータを送信するチャネルにロックされます.ただし、Buffered Channelは、受信者が受信する準備ができていなくても、指定されたバッファに従ってデータを送信し、他の操作を継続することができる.Buffered Channelは、「make(chan type,N)」関数で作成し、2番目のパラメータNに使用するバッファ数を加えることができます.
package main
 
import "fmt"
 
func main() {
    ch := make(chan string, 1)
    sendChan(ch)
    receiveChan(ch)
}
 
func sendChan(ch chan<- string) {
    ch <- "Data"
}
 
func receiveChan(ch <-chan string) {
    data := <-ch
    fmt.Println(data)
}
上記のように、値を受け入れたgoroutineはチャネルから抽出され、「data」という新しい変数に割り当てられます.
n/a.結論
Goはgoroutineとchannelを用いてCSPモデルを実装しようとした.goroutine間でチャネル伝達リソースを利用して処理することがこのコンテンツの核心である.
理解できない内容
  • 情報伝達上手→分散上手
    情報伝達に基づいた技術は、ActorやCSPなどの重要な役割を果たすだろう.
    Goの同期性は文法的な要因だけではない.
  • Goで同期性を説明する場合、主に使用される文は次のとおりです.
  • "Do not communicate by sharing memory; instead, share memory by communicating"
    共有メモリで通信しないでください.
    そのため,代わりに通信によりメモリを割り当てる.
    Threedたちの「待つ」ことで、Threed同士が交換されるときにもっと適した考え方?
    (この部分は理解できません)
  • 軽量化スレッド.これらはオペレーティングシステムのスレッド間で多重化されていますよね?もし1ブロックあったら、他のものはまだ続けられますか??
  • 実際のスレッドではないのは、常に並列ではないからです.しかし,多重化と同期により,同時に動作すると考えられる.
    相互アクセスで処理するのではなく、メモリ(リソース)を共有します.どうすればいいのシュワル
    リファレンス
    Go Programming(Goroutine)の例
    高言語での同期モデル