ch := make(chan int, 1)
Go 言語での Goroutine とチャネルの予備調査
この記事では、Go 言語の Goroutine とチャネルについて予備的に理解することができます。
Go 言語の CSP
同時実行モデルの実装には、2 つの主要コンポーネントが含まれています。1 つは Goroutine
で、もう 1 つはチャンネル
。この記事ではその基本的な使い方と注意点を紹介します。
Goroutine
Goroutine
は、Go
アプリケーションの基本的な実行ユニットであり、軽量のユーザーレベルのスレッドです。 、最下層は coroutine
(コルーチン) によって実現される同時実行です。ご存知のとおり、コルーチンはユーザー モードで実行されるユーザー スレッドであるため、Go
プログラムの実行中に Goroutine
もスケジュールされます。
#基本的な使い方
構文: go function/methodgo キーワード function/method を通じて ## を作成できます#ゴルーチン
。 コード例:
import ( "fmt" "time" ) func printGo() { fmt.Println("具名函数") } type G struct { } func (g G) g() { fmt.Println("方法") } func main() { // 基于具名函数创建 goroutine go printGo() // 基于方法创建 goroutine g := G{} go g.g() // 基于匿名函数创建 goroutine go func() { fmt.Println("匿名函数") }() // 基于闭包创建 goroutine i := 0 go func() { i++ fmt.Println("闭包") }() time.Sleep(time.Second) // 避免 main goroutine 结束后,其创建的 goroutine 来不及运行,因此在此休眠 1 秒 }
実行結果:
闭包 具名函数 方法 匿名函数
複数の
Goroutine が存在する場合、実行順序は固定されません。したがって、印刷するたびに結果が異なります。 コードからわかるように、
キーワードを使用して、名前付き関数
/ に基づいて groutin を作成できます。 Method、Goroutine
も 匿名関数 /closures に基づいて作成できます。 それでは、
はどのようにして終了するのでしょうか?通常の状況では、Goroutine
関数の実行が終了するか、実行が戻る限り、それは Goroutine
の終了を意味します。 Goroutine
の関数またはメソッドに戻り値がある場合、Goroutine
が終了すると無視されます。
channel
は、Go 同時実行モデルにおいて重要な役割を果たします。これは、Goroutine
間の通信を実装するために使用でき、また、Goroutine
間の同期を実装するためにも使用できます。
#channel
は複合データ型のため、宣言時に channel 内の要素を指定する必要があります。 ### タイプ。
宣言構文: var ch chan string
である上記のコードを通じて、要素タイプが
string
channel を宣言します。
string 型の要素のみを保存できます。
channel は参照型であり、データを書き込むために初期化する必要があります。
make によって初期化されます。
import ( "fmt" ) func main() { var ch chan string ch = make(chan string, 1) // 打印 chan 的地址 fmt.Println(ch) // 向 ch 发送 "Go" 数据 ch <- "Go" // 从 ch 中接收数据 s := <-ch fmt.Println(s) // Go }
ch <- xxx を通じて、x := < を介して channel
変数 ch
にデータを送信できます。 ;- ch データは
channel 変数
ch から受信できます。
バッファ付きチャネルとバッファなしチャネル
チャネル
の初期化時に容量が指定されていない場合は、バッファなし ##チャネルが作成されます。: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>ch := make(chan string)</pre><div class="contentsignin">ログイン後にコピー</div></div>
バッファリングされていない channel
の送信操作と受信操作は同期しています。送信操作が実行されると、対応する
がブロックされます。受信操作を実行する別の Goroutine
があり、その逆も同様です。送信操作と実行操作を同じゴルーチンの下に置くとどうなるでしょうか?次のコードを見てください: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>import (
"fmt"
)
func main() {
ch := make(chan int)
// 发送数据
ch <- 1 // fatal error: all goroutines are asleep - deadlock!
// 接收数据
n := <-ch
fmt.Println(n)
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
プログラムを実行すると、ch <-
で
が発生し、すべての Goroutine にプロンプトが表示されます。
休止状態では、デッドロック状態になります。この状況を回避するには、channel
の送受信操作を別の Goroutine
で実行する必要があります。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
// 发送数据
ch <- 1
}()
// 接收数据
n := <-ch
fmt.Println(n) // 1
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
上記の例から結論付けることができます: バッファリングされていない channel
の送信および受信操作は 2 つの異なる
で実行する必要があります。そうしないと、発生しますデッドロック
画像。 容量が指定されている場合、バッファ付き
channel
ch := make(chan string, 5)
バッファ付き channel
およびバッファなし
は異なります。送信操作を実行するとき、channel
のバッファーがいっぱいでない限り、バッファーがいっぱいになるまで Goroutine
はハングしません。送信操作を実行すると、Goroutine
がハングします。コード例: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>func main() {
ch := make(chan int, 1)
// 发送数据
ch <- 1
ch <- 2 // fatal error: all goroutines are asleep - deadlock!
}</pre><div class="contentsignin">ログイン後にコピー</div></div>
両方とも送信できるチャネルの送信専用タイプと受信専用タイプを宣言します
channel# and accept ##ch := make(chan int, 1)
ログイン後にコピー
ch := make(chan int, 1)
- channel
- 変数は上記のコードを通じて取得され、それに対して送受信操作を実行できます。
channel
ch := make(<-chan int, 1)
ログイン後にコピーchannel - 変数は上記のコードを通じて取得されており、受信のみが可能です。
送信のみchannel
ch := make(chan<- int, 1)
ログイン後にコピーchannel - 変数は上記のコードを通じて取得され、送信のみ可能です。
通常只发送 channel
类型和只接收 channel
类型,会被用作函数的参数类型或返回值:
func send(ch chan<- int) { ch <- 1 } func recv(ch <-chan int) { <-ch }
channel 的关闭
通过内置函 close(c chan<- Type)
,可以对 channel
进行关闭。
在发送端关闭
channel
在
channel
关闭之后,将不能对channel
执行发送操作,否则会发生panic
,提示channel
已关闭。func main() { ch := make(chan int, 5) ch <- 1 close(ch) ch <- 2 // panic: send on closed channel }
ログイン後にコピー管道
channel
之后,依旧可以对channel
执行接收操作,如果存在缓冲区的情况下,将会读取缓冲区的数据,如果缓冲区为空,则获取到的值为channel
对应类型的零值。import "fmt" func main() { ch := make(chan int, 5) ch <- 1 close(ch) fmt.Println(<-ch) // 1 n, ok := <-ch fmt.Println(n) // 0 fmt.Println(ok) // false }
ログイン後にコピー如果通过 for-range 遍历
channel
时,中途关闭channel
则会导致for-range
循环结束。
小结
本文首先介绍了 Goroutine
的创建方式以及其退出的时机是什么。
其次介绍了如何创建 channel
类型变量的有缓冲与无缓冲的创建方式。需要注意的是,无缓冲的 channel
发送与接收操作,需要在两个不同的 Goroutine
中执行,否则会发送 error
。
接下来介绍如何定义只发送和只接收的 channel
类型。通常只发送 channel
类型和只接收 channel
类型,会被用作函数的参数类型或返回值。
最后介绍了如何关闭 channel
,以及关闭之后的一些注意事项。
以上がGo 言語での Goroutine とチャネルの予備調査の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

GO言語で構造を定義する2つの方法:VARとタイプのキーワードの違い。構造を定義するとき、GO言語はしばしば2つの異なる執筆方法を見ます:最初...

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?ゴーランドを使用するためにGolandを使用する場合、多くの開発者はカスタム構造タグに遭遇します...

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

VSCODEユーザーのGolang Generic Function Typeの制約の自動削除は、VSCODEを使用してGolangコードを書くときに奇妙な問題に遭遇する可能性があります。いつ...
