Pelajari bagaimana goroutine dan saluran mengaktifkan konkurensi yang efisien dalam program Go Anda.
Concurrency adalah aspek penting dari pengembangan perangkat lunak modern karena memungkinkan program menangani banyak tugas secara bersamaan secara efisien. Anda dapat menulis program yang menjalankan berbagai operasi yang menghasilkan peningkatan kinerja, daya tanggap, dan penggunaan sumber daya.
Concurrency adalah salah satu fitur yang bertanggung jawab atas adopsi cepat Go. Dukungan bawaan Go untuk pemrograman bersamaan dianggap mudah sambil membantu menghindari jebakan umum seperti kondisi balapan dan kebuntuan.
Konkurensi di Go
Go memberikan dukungan kuat untuk konkurensi melalui berbagai mekanisme, semuanya tersedia di pustaka standar dan rantai alatnya. Pergi program mencapai konkurensi melalui goroutine dan saluran.
Goroutine ringan, menjalankan fungsi secara independen yang berjalan bersamaan dengan goroutine lain dalam ruang alamat yang sama. Goroutine memungkinkan banyak tugas untuk maju secara bersamaan tanpa manajemen utas eksplisit. Goroutine lebih ringan daripada thread sistem operasi dan Go dapat menjalankan ribuan atau bahkan jutaan goroutine secara bersamaan secara efisien.
Saluran adalah mekanisme komunikasi untuk koordinasi dan berbagi data antar goroutine. Saluran adalah saluran yang diketik yang memungkinkan goroutine mengirim dan menerima nilai. Saluran menyediakan sinkronisasi untuk memastikan berbagi data yang aman di antara goroutine sambil mencegah kondisi balapan dan masalah konkurensi umum lainnya.
Dengan menggabungkan goroutine dan saluran, Go menyediakan model konkurensi yang andal dan lugas yang menyederhanakan pengembangan program konkuren dengan tetap menjaga keamanan dan efisiensi. Mekanisme ini memungkinkan Anda untuk menggunakan dengan mudah prosesor multicore dan membangun aplikasi yang sangat skalabel dan responsif.
Cara Menggunakan Goroutine untuk Eksekusi Kode Bersamaan
Runtime Go mengelola goroutine. Goroutine memiliki tumpukannya sendiri, memungkinkan mereka memiliki tapak yang ringan dengan ukuran tumpukan awal beberapa kilobyte.
Goroutine dimultipleks ke beberapa utas OS oleh runtime Go. Penjadwal runtime Go menjadwalkannya ke thread yang tersedia dengan mendistribusikan beban kerja secara efisien, memungkinkan eksekusi bersamaan beberapa goroutine pada thread OS yang lebih sedikit.
Membuat goroutine sangatlah mudah. Anda akan menggunakan pergi keyword diikuti dengan pemanggilan fungsi untuk mendeklarasikan goroutine.
fungsiutama() {
pergi fungsi1() // Buat dan jalankan goroutine untuk function1
pergi fungsi2() // Buat dan jalankan goroutine untuk function2// ...
}fungsifunction1() {
// Kode untuk fungsi1
}
fungsifunction2() {
// Kode untuk fungsi2
}
Saat program memanggil fungsi1() Dan fungsi2() dengan pergi kata kunci, runtime Go mengeksekusi fungsi secara bersamaan sebagai goroutine.
Berikut adalah contoh penggunaan goroutine yang mencetak teks ke konsol:
kemasan utama
impor (
"fmt"
"waktu"
)fungsiprintText() {
untuk saya := 1; saya <= 5; saya++ {
fmt. Cetak("Mencetak teks", Saya)
waktu. Tidur(1 * waktu. Kedua)
}
}fungsiutama() {
pergi printText() // Memulai goroutine untuk menjalankan fungsi printText secara bersamaan// Lakukan tugas lain di goroutine utama
untuk saya := 1; saya <= 5; saya++ {
fmt. Cetak("Melakukan tugas lain", Saya)
waktu. Tidur(500 * waktu. Mili detik)
}
// Tunggu hingga goroutine selesai
waktu. Tidur(6 * waktu. Kedua)
}
Itu printText fungsi berulang kali mencetak beberapa teks ke konsol dengan a untuk loop yang berjalan lima kali mengikuti penundaan satu detik antara setiap pernyataan dengan paket waktu.
Itu utama fungsi memulai goroutine dengan memanggil pergi printText, yang meluncurkan printText berfungsi sebagai goroutine bersamaan terpisah yang memungkinkan fungsi untuk mengeksekusi secara bersamaan dengan sisa kode di utama fungsi.
Terakhir, untuk memastikan bahwa program tidak keluar sebelum printText goroutine selesai, the waktu. Tidur fungsi menjeda goroutine utama selama enam detik. Dalam skenario dunia nyata, Anda akan menggunakan mekanisme sinkronisasi seperti saluran atau grup tunggu untuk mengoordinasikan eksekusi goroutine.
Menggunakan Saluran untuk Komunikasi dan Sinkronisasi
Goroutine memiliki dukungan bawaan untuk komunikasi dan sinkronisasi melalui saluran, membuat penulisan bersamaan kode lebih mudah daripada utas tradisional, yang seringkali memerlukan mekanisme sinkronisasi manual seperti kunci dan semafor.
Anda dapat menganggap saluran sebagai saluran untuk aliran data antar goroutine. Satu goroutine dapat mengirim nilai ke saluran, dan goroutine lain dapat menerima nilai itu dari saluran. Mekanisme ini memastikan bahwa pertukaran data aman dan tersinkronisasi.
Anda akan menggunakan operator untuk mengirim dan menerima data melalui saluran.
Berikut adalah contoh yang menunjukkan penggunaan dasar saluran untuk komunikasi antara dua goroutine:
fungsiutama() {
// Buat saluran tanpa buffer dengan tipe string
ch := membuat(chanrangkaian)// Goroutine 1: Mengirim pesan ke saluran
pergifungsi() {
ch "Halo, Saluran!"
}()
// Goroutine 2: Menerima pesan dari saluran
pesan := fmt. Cetak (pesan) // Keluaran: Halo, Saluran!
}
Saluran di utama function adalah saluran tanpa buffer bernama ch dibuat dengan membuat() fungsi. Goroutine pertama mengirimkan pesan "Hello, Channel!" ke dalam saluran menggunakan operator, dan goroutine kedua menerima pesan dari saluran menggunakan operator yang sama. Akhirnya, utama fungsi mencetak pesan yang diterima ke konsol.
Anda dapat menentukan saluran yang diketik. Anda akan menentukan jenis saluran pada pembuatan. Berikut adalah contoh yang menunjukkan penggunaan berbagai jenis saluran:
fungsiutama() {
// Saluran tanpa buffer
bab 1 := membuat(chanint)// Saluran buffer dengan kapasitas 3
ch2 := membuat(chanrangkaian, 3)// Mengirim dan menerima nilai dari saluran
ch1 42// Kirim nilai ke ch1
nilai1 := // Menerima nilai dari ch1
ch2 "Halo"// Kirim nilai ke ch2
nilai2 := // Menerima nilai dari ch2
}
Itu utama fungsi membuat dua saluran: bab 1 adalah saluran bilangan bulat tanpa buffer, sementara ch2 adalah saluran string buffered dengan kapasitas 3. Anda dapat mengirim dan menerima nilai ke dan dari saluran ini menggunakan operator (nilai harus dari tipe yang ditentukan).
Anda dapat menggunakan saluran sebagai mekanisme sinkronisasi untuk mengoordinasikan eksekusi goroutine dengan memanfaatkan sifat pemblokiran operasi saluran.
fungsiutama() {
ch := membuat(chanbool)pergifungsi() {
fmt. Cetak("Gorutin 1")
ch BENAR// Penyelesaian sinyal
}()pergifungsi() {
// Tunggu sinyal penyelesaian dari Goroutine 1
fmt. Cetak("Gorutin 2")
}()
// Tunggu sinyal penyelesaian dari Goroutine 2
fmt. Cetak("Groutine utama")
}
Itu ch saluran adalah boolean. Dua goroutine berjalan bersamaan di utama fungsi. Goroutine 1 menandai penyelesaiannya dengan mengirimkan a BENAR nilai ke saluran ch. Goroutine 2 menunggu sinyal penyelesaian dengan menerima nilai dari saluran. Terakhir, goroutine utama menunggu sinyal penyelesaian dari goroutine dua.
Anda Dapat Membuat Aplikasi Web di Go With Gin
Anda dapat membuat aplikasi web berperforma tinggi di Go dengan Gin sambil memanfaatkan fitur konkurensi Go.
Anda dapat menggunakan Gin untuk menangani perutean HTTP dan middleware secara efisien. Memanfaatkan dukungan konkurensi bawaan Go dengan menggunakan goroutine dan saluran untuk tugas seperti kueri basis data, panggilan API, atau operasi pemblokiran lainnya.