Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Penerbitan mesej dan model langganan dalam bahasa Go

Penerbitan mesej dan model langganan dalam bahasa Go

王林
王林asal
2023-06-01 09:21:291436semak imbas

Dengan pembangunan berterusan dan peningkatan permintaan aplikasi moden, semakin ramai pembangun mula mengalihkan perhatian mereka kepada mekanisme pemesejan. Dalam kes ini, terdapat jenis model mesej yang dibimbangkan oleh ramai pembangun, dan itu ialah model penerbitan dan langganan mesej. Model ini melaksanakan penghantaran mesej dengan cara yang mudah dan berkesan dan digunakan secara meluas dalam seni bina teragih. Dalam model ini, bahasa Go juga mempunyai kaedah pelaksanaannya yang unik.

Artikel ini akan memperkenalkan model penerbitan dan langganan mesej dalam bahasa Go, termasuk cara menggunakan Saluran dalam bahasa Go untuk melaksanakan dan menggunakan model penerbitan dan langganan mesej serta cara melaksanakan mesej ringkas dalam baris gilir bahasa Go .

1 Pengenalan kepada Saluran bahasa Go

Saluran ialah mekanisme yang digunakan untuk mencapai komunikasi serentak dalam bahasa Go. Saluran menyediakan cara untuk memindahkan data antara gorouti (coroutine) yang berbeza dan boleh digunakan untuk menyegerakkan pelaksanaan antara goroutines. Saluran yang menghantar data dari satu goroutine ke yang lain adalah selamat untuk benang dan boleh mengelakkan keadaan perlumbaan.

Dalam bahasa Go, gunakan fungsi make untuk mencipta Saluran. Sintaks fungsi make adalah seperti berikut:

make(chan T)

Antaranya, T mewakili jenis elemen dalam Saluran. Contohnya, untuk mencipta Saluran yang menghantar jenis integer, anda boleh menggunakan kod berikut:

ch := make(chan int)

2. Pelaksanaan penerbitan mesej dan model langganan dalam bahasa Go

Pelaksanaan penerbitan dan langganan mesej model dalam bahasa Go Kaedahnya sangat mudah, hanya gunakan Saluran. Contoh kod model penerbitan dan langganan yang disyorkan dalam bahasa Go adalah seperti berikut:

package main

import (
    "fmt"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        for {
            str := <-ch1
            ch2 <- "go " + str
        }
    }()

    for i := 0; i < 5; i++ {
        ch1 <- fmt.Sprintf("message %d", i)
    }

    for i := 0; i < 5; i++ {
        fmt.Println(<-ch2)
    }
}

Blok kod di atas menggunakan dua Saluran: ch1 dan ch2. Kami mentakrifkan goroutine yang bertanggungjawab untuk membaca mesej daripada ch1, menukarnya kepada rentetan dan memberi awalan dengan "pergi", dan kemudian menghantar mesej baharu ini melalui ch2. Kemudian kami menjana beberapa mesej dalam goroutine utama dan menghantarnya ke ch1, dan kemudian kami menerima dan mencetak mesej baharu ini daripada ch2. Kaedah ini ialah cara biasa untuk melaksanakan penerbitan mesej dan model langganan dalam bahasa Go.

3 Melaksanakan baris gilir mesej ringkas dalam bahasa Go

Ia juga sangat mudah untuk melaksanakan baris gilir mesej ringkas dalam bahasa Go. Anda hanya perlu menggunakan Saluran dan goroutine.

Pertama, kami mentakrifkan jenis baris gilir:

type Queue struct {
    items []string
    lock  sync.Mutex
    ch    chan bool
}

Jenis baris gilir ini mempunyai tiga pembolehubah ahli penting: item, kunci dan ch. Antaranya, item digunakan untuk menyimpan mesej dalam baris gilir, kunci digunakan untuk melindungi operasi tulis dan baca baris gilir, dan ch digunakan untuk memberitahu baris gilir bahawa mesej baharu telah tiba. Pemberitahuan dilaksanakan dengan menghantar nilai bool ke Saluran.

Kami juga perlu menentukan kaedah untuk menambah mesej pada baris gilir:

func (q *Queue) Add(item string) {
    q.lock.Lock()
    defer q.lock.Unlock()

    q.items = append(q.items, item)
    q.ch <- true
}

Kaedah ini selamat untuk benang dan boleh mengelakkan keadaan perlumbaan. Ia mula-mula memperoleh kunci baris gilir, kemudian menambah mesej pada baris gilir, dan akhirnya menghantar nilai bool ke Saluran.

Kami juga perlu mentakrifkan kaedah untuk mendapatkan mesej untuk baris gilir:

func (q *Queue) Get() (string, bool) {
    q.lock.Lock()
    defer q.lock.Unlock()

    if len(q.items) == 0 {
        return "", false
    }

    item := q.items[0]
    q.items = q.items[1:]

    return item, true
}

Kaedah ini juga selamat untuk benang terlebih dahulu memperoleh kunci baris gilir dan kemudian menyemak sama ada baris gilir kosong. Jika baris gilir kosong Mengembalikan palsu. Jika tidak, ia mendapat mesej daripada ketua baris gilir, mengalih keluar elemen kepala dan mengembalikan mesej dan nilai sebenar.

Kod sampel untuk menggunakan baris gilir ini adalah seperti berikut:

package main

import (
    "fmt"
    "time"
)

func main() {
    q := Queue{
        items: []string{},
        ch:    make(chan bool),
    }

    // 启动一个goroutine更新队列
    go func() {
        for {
            select {
            case <-q.ch:
                for {
                    item, ok := q.Get()
                    if !ok {
                        break
                    }
                    fmt.Println(item)
                }
            }
        }
    }()

    // 向队列中添加一些消息
    for i := 0; i < 5; i++ {
        q.Add(fmt.Sprintf("message %d", i))
        time.Sleep(time.Second)
    }
}

Dalam kod di atas, kami mentakrifkan pembolehubah q jenis Queue, kemudian mulakan goroutine untuk mengemas kininya, dan akhirnya menambahnya ke baris gilir Menambah beberapa mesej. Goroutine menggunakan pernyataan pilih untuk mendapatkan pemberitahuan mesej daripada Saluran, dan mendapatkan semua mesej dalam baris gilir dan mencetaknya.

Ringkasan

Model penerbitan dan langganan mesej dalam bahasa Go adalah sangat mudah dan cekap serta mempunyai keselamatan urutan semula jadi kerana penggunaan Saluran. Artikel ini memperkenalkan cara melaksanakan model penerbitan dan langganan mesej dalam bahasa Go dan cara melaksanakan baris gilir mesej ringkas dalam bahasa Go. Selepas mempelajari kandungan ini, anda boleh menggunakannya untuk melaksanakan pelbagai tugas pemprosesan tak segerak dan meningkatkan prestasi serentak program.

Atas ialah kandungan terperinci Penerbitan mesej dan model langganan dalam bahasa Go. 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