Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara melaksanakan berbilang coroutine untuk membaca dan menulis Saluran yang sama pada masa yang sama di Golang

Cara melaksanakan berbilang coroutine untuk membaca dan menulis Saluran yang sama pada masa yang sama di Golang

WBOY
WBOYasal
2023-08-07 14:25:061811semak imbas

Cara melaksanakan berbilang coroutine untuk membaca dan menulis Saluran yang sama pada masa yang sama dalam pengaturcaraan Golang

In Go, goroutine digunakan secara meluas untuk mencapai keselarasan dan selari. Saluran ialah struktur data khas yang digunakan untuk komunikasi dan penyegerakan antara coroutine. Saluran menyediakan cara yang selamat untuk berkongsi data antara coroutine.

Dalam sesetengah kes, kita mungkin memerlukan berbilang coroutine untuk membaca atau menulis Saluran yang sama pada masa yang sama. Oleh kerana Saluran menyekat secara lalai, jika langkah khas tidak diambil, berbilang coroutine akan menyekat satu sama lain, menyebabkan program gagal berjalan seperti biasa. Seterusnya, saya akan membincangkan dua penyelesaian biasa.

Penyelesaian 1: Gunakan Saluran penimbal

Saluran Penampan ialah saluran dengan kapasiti terhad. Apabila membuat Saluran, kami boleh menentukan kapasitinya. Apabila penimbal Saluran tidak penuh, operasi tulis boleh diselesaikan serta-merta apabila penimbal tidak kosong, operasi baca juga boleh selesai dengan serta-merta. Baca dan tulis blok operasi hanya apabila penimbal penuh atau kosong.

Berikut ialah contoh kod:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个容量为1的缓冲 Channel
    ch := make(chan int, 1)

    // 启动多个协程,并同时写入 Channel
    for i := 1; i <= 5; i++ {
        go func(i int) {
            ch <- i
            fmt.Printf("协程 %d 写入数据
", i)
        }(i)
    }

    // 读取 Channel 中的数据
    time.Sleep(time.Second) // 休眠 1 秒,等待协程写入数据
    for i := 1; i <= 5; i++ {
        fmt.Printf("读取到数据:%d
", <-ch)
    }
}

Dalam kod di atas, kami mencipta Saluran penimbal ch dengan kapasiti 1. Kemudian 5 coroutine dimulakan dan mereka menulis data ke Saluran ch pada masa yang sama. Oleh kerana Saluran ditimbal, penulisan selesai serta-merta. Akhir sekali, kami mengulangi data dalam Saluran dan melaksanakan operasi baca. ch。然后启动了 5 个协程,它们同时向 Channel ch 写入数据。由于 Channel 是缓冲的,所以写入操作可以立即完成。最后,我们遍历 Channel 中的数据,并进行读取操作。

解决方案二:使用带有 select 语句的无缓冲 Channel

无缓冲 Channel 是一种没有容量的 Channel。在这种情况下,读取和写入操作都会阻塞,直到有另一个协程执行相反的操作。但我们可以使用 select 语句来实现同时读写无缓冲 Channel,避免协程相互阻塞。

下面是一个示例代码:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建无缓冲 Channel
    ch := make(chan int)

    // 启动多个协程,并同时写入 Channel
    for i := 1; i <= 5; i++ {
        go func(i int) {
            select {
            case ch <- i:
                fmt.Printf("协程 %d 写入数据
", i)
            default:
                fmt.Printf("协程 %d 无法写入数据
", i)
            }
        }(i)
    }

    // 读取 Channel 中的数据
    time.Sleep(time.Second) // 休眠 1 秒,等待协程写入数据
    for i := 1; i <= 5; i++ {
        select {
        case data := <-ch:
            fmt.Printf("读取到数据:%d
", data)
        default:
            fmt.Println("无法读取数据")
        }
    }
}

上述代码中,我们创建了一个无缓冲 Channel ch。与解决方案一不同的是,在写入数据时我们使用了 select 语句,并在 case 中处理写入成功和失败的情况。相同地,在读取数据时我们也使用了 select

Penyelesaian 2: Gunakan Saluran yang tidak ditimbal dengan pernyataan pilihan

Saluran yang tidak ditimbal ialah Saluran tanpa kapasiti. Dalam kes ini, kedua-dua operasi baca dan tulis blok sehingga coroutine lain melakukan operasi bertentangan. Tetapi kita boleh menggunakan pernyataan select untuk membaca dan menulis Saluran yang tidak ditimbal pada masa yang sama untuk mengelakkan coroutine menyekat satu sama lain.

Berikut ialah contoh kod:

rrreee

Dalam kod di atas, kami mencipta Saluran ch yang tidak dibuffer. Perbezaan daripada penyelesaian satu ialah kami menggunakan pernyataan select semasa menulis data dan mengendalikan kejayaan dan kegagalan penulisan dalam case. Begitu juga, kami juga menggunakan pernyataan select semasa membaca data untuk mengendalikan situasi di mana data tidak boleh dibaca. 🎜🎜Ringkasan: 🎜🎜Dengan menggunakan Saluran penimbal atau Saluran tidak penimbal dengan penyataan pilihan, kita boleh mencapai berbilang coroutine membaca dan menulis Saluran yang sama pada masa yang sama. Penyelesaian ini boleh meningkatkan kecekapan program anda dan mengelakkan coroutine menghalang satu sama lain. 🎜🎜Sudah tentu, sebagai tambahan kepada penyelesaian di atas, terdapat teknik pengaturcaraan serentak yang lebih maju, seperti menggunakan WaitGroup, Mutex, dll. Dalam aplikasi sebenar, kita perlu memilih mekanisme kawalan konkurensi yang sesuai berdasarkan keperluan khusus. Saya harap artikel ini dapat membantu anda lebih memahami dan menggunakan pengaturcaraan serentak di Golang. 🎜

Atas ialah kandungan terperinci Cara melaksanakan berbilang coroutine untuk membaca dan menulis Saluran yang sama pada masa yang sama di Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn