Penerokaan awal Goroutine dan saluran dalam bahasa Go
Artikel ini akan memberi anda pemahaman awal tentang Goroutine dan saluran dalam bahasa Go. Saya harap ia akan membantu anda!
Pelaksanaan model konkurensi CSP
bahasa Go terdiri daripada dua komponen utama: satu ialah Goroutine
dan satu lagi ialah channel
. Artikel ini akan memperkenalkan penggunaan asas dan langkah berjaga-jaga mereka.
Goroutine
Goroutine
ialah unit pelaksanaan asas bagi aplikasi Go
Ia adalah urutan peringkat pengguna yang ringan, dan lapisan bawahnya melalui coroutine
(coroutine) untuk mencapai keselarasan. Seperti yang kita sedia maklum, coroutine ialah urutan pengguna yang berjalan dalam mod pengguna, jadi Goroutine
juga dijadualkan apabila program Go
sedang berjalan.
Penggunaan asas
Sintaks: go + function/method
Anda boleh mencipta kata kunci go + function/method Goroutine
.
Contoh kod:
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 秒 }
Hasil pelaksanaan:
闭包 具名函数 方法 匿名函数
Apabila berbilang Goroutine
wujud, perintah pelaksanaannya tidak tetap. Oleh itu, keputusan akan berbeza setiap kali anda mencetak.
Seperti yang dapat dilihat daripada kod, melalui kata kunci go
, kita boleh mencipta berdasarkan fungsi bernama / kaedahgoroutine
, atau berdasarkan fungsi tanpa nama / Penutupan mencipta goroutine
.
Jadi bagaimanakah Goroutine
keluar? Dalam keadaan biasa, selagi pelaksanaan fungsi Goroutine
tamat, atau pelaksanaan kembali, ia bermakna keluar daripada Goroutine
. Jika fungsi atau kaedah Goroutine
mempunyai nilai pulangan, ia akan diabaikan apabila Goroutine
keluar.
saluran
channel
memainkan peranan penting dalam model konkurensi Go. Ia boleh digunakan untuk melaksanakan komunikasi antara Goroutine
dan penyegerakan antara Goroutine
.
Operasi asas saluran
channel
ialah jenis data komposit dan jenis elemen dalam channel
perlu dinyatakan semasa mengisytiharkan.
Sintaks pengisytiharan: rentetan var ch chan
Isytihar string
dengan jenis elemen channel
melalui kod di atas, yang hanya boleh menyimpan string
elemen jenis. channel
ialah jenis rujukan dan mesti dimulakan sebelum data boleh ditulis ia dimulakan oleh 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 }
Anda boleh menghantar data ke ch <- xxx
pembolehubah channel
melalui ch
dan anda boleh menerima data daripada x := <- ch
pembolehubah channel
melalui ch
.
Saluran buffer dan saluran tidak buffer
Jika kapasiti tidak dinyatakan semasa memulakan channel
, channel
yang tidak ditimbal akan dibuat:
ch := make(chan string)
Operasi penghantaran dan penerimaan channel
yang tidak dibuffer adalah segerak Selepas melakukan operasi penghantaran, Goroutine
yang sepadan akan menyekat sehingga satu lagi Goroutine
melakukan operasi menerima, dan begitu juga sebaliknya. Apakah yang berlaku jika operasi hantar dan operasi pelaksanaan diletakkan di bawah Goroutine yang sama? Lihat kod berikut:
import ( "fmt" ) func main() { ch := make(chan int) // 发送数据 ch <- 1 // fatal error: all goroutines are asleep - deadlock! // 接收数据 n := <-ch fmt.Println(n) }
Selepas program dijalankan, anda akan mendapat ch <-
di fatal error
, menunjukkan bahawa semua Goroutine
berada dalam keadaan tidak aktif, iaitu kebuntuan . Untuk mengelakkan situasi ini, kita perlu melaksanakan operasi penghantaran dan penerimaan channel
dalam Goroutine
yang berbeza.
import ( "fmt" ) func main() { ch := make(chan int) go func() { // 发送数据 ch <- 1 }() // 接收数据 n := <-ch fmt.Println(n) // 1 }
Daripada contoh di atas, kita boleh menyimpulkan bahawa operasi penghantaran dan penerimaan channel
yang tidak ditimbal mesti dilakukan dalam dua Goroutine
yang berbeza, jika tidak deadlock
imej akan berlaku.
Jika kapasiti ditentukan, penimbal channel
dicipta:
ch := make(chan string, 5)
Terdapat perbezaan antara penimbal channel
dan tidak penimbal chennel
, apabila melakukan operasi hantar, selagi penimbal channel
tidak penuh, Goroutine
tidak akan tergantung sehingga penimbal penuh, melakukan operasi hantar ke channel
akan menyebabkan Goroutine
hang. Contoh kod:
func main() { ch := make(chan int, 1) // 发送数据 ch <- 1 ch <- 2 // fatal error: all goroutines are asleep - deadlock! }
Isytiharkan jenis hantar sahaja dan terima sahaja saluran
Boleh kedua-duanya menghantar dan menerima
channel
ch := make(chan int, 1)
Salin selepas log masukPembolehubah
channel
diperoleh melalui kod di atas, dan kami boleh melakukan operasi penghantaran dan penerimaan padanya.Hanya menerima
channel
ch := make(<-chan int, 1)
Salin selepas log masukyang diperolehi melalui pembolehubah
channel
di atas, kami hanya boleh menerima operasi padanya.Hanya dihantar
channel
ch := make(chan<- int, 1)
Salin selepas log masukPembolehubah
channel
diperoleh melalui kod di atas dan kami hanya boleh menghantarnya.
通常只发送 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 }
Salin selepas log masuk管道
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 }
Salin selepas log masuk如果通过 for-range 遍历
channel
时,中途关闭channel
则会导致for-range
循环结束。
小结
本文首先介绍了 Goroutine
的创建方式以及其退出的时机是什么。
其次介绍了如何创建 channel
类型变量的有缓冲与无缓冲的创建方式。需要注意的是,无缓冲的 channel
发送与接收操作,需要在两个不同的 Goroutine
中执行,否则会发送 error
。
接下来介绍如何定义只发送和只接收的 channel
类型。通常只发送 channel
类型和只接收 channel
类型,会被用作函数的参数类型或返回值。
最后介绍了如何关闭 channel
,以及关闭之后的一些注意事项。
Atas ialah kandungan terperinci Penerokaan awal Goroutine dan saluran dalam bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Dua cara untuk menentukan struktur dalam bahasa Go: perbezaan antara VAR dan jenis kata kunci. Apabila menentukan struktur, pergi bahasa sering melihat dua cara menulis yang berbeza: pertama ...

Perbezaan antara percetakan rentetan dalam bahasa Go: perbezaan kesan menggunakan fungsi println dan rentetan () sedang ...

Perpustakaan mana yang dibangunkan oleh syarikat besar atau projek sumber terbuka yang terkenal? Semasa pengaturcaraan di GO, pemaju sering menghadapi beberapa keperluan biasa, ...

Apa yang perlu saya lakukan jika label struktur tersuai di Goland tidak dipaparkan? Apabila menggunakan Goland untuk Pembangunan Bahasa GO, banyak pemaju akan menghadapi tag struktur tersuai ...

Masalah menggunakan redisstream untuk melaksanakan beratur mesej dalam bahasa Go menggunakan bahasa Go dan redis ...

Penghapusan automatik Golang Generik Jenis Kekangan Jenis dalam Pengguna VSCode mungkin menghadapi masalah yang aneh ketika menulis kod Golang menggunakan vscode. Bila ...
