Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menghentikan goroutine dalam golang (empat kaedah)

Bagaimana untuk menghentikan goroutine dalam golang (empat kaedah)

PHPz
PHPzasal
2023-04-11 10:42:061343semak imbas

Golang ialah bahasa yang direka untuk membina pengaturcaraan serentak dan cekap Ia menyediakan mekanisme goroutine yang mudah dan cekap, yang boleh meningkatkan kecekapan dan prestasi program dengan sangat baik. Namun, apabila kita menggunakan goroutine, ada beberapa perkara yang perlu kita ambil perhatian, seperti cara menghentikan goroutine daripada berjalan. Berikut akan memberi tumpuan kepada cara menghentikan goroutine.

Asas Goroutine

Sebelum memahami cara menghentikan goroutine, kita perlu terlebih dahulu memahami pengetahuan asas goroutine. Goroutine ialah pelaksanaan utas ringan dalam bahasa Golang dan boleh dijalankan pada satu atau lebih utas. Ia diuruskan oleh sistem masa jalan Go dan merupakan unit perlaksanaan yang bebas dan ringan. Berbeza daripada utas tradisional, goroutine dijadualkan secara automatik oleh sistem runtime Go semasa berjalan, dan model penjadualannya juga sangat cekap ia bukan sahaja dapat menyokong konkurensi tinggi dengan baik, tetapi juga memanfaatkan sepenuhnya CPU berbilang teras.

Cara mencipta goroutine

Dalam bahasa Go, kita boleh mencipta goroutine dalam dua cara biasa berikut:

  1. Gunakan kata kunci go
go func() {
    //goroutine运行的代码
}()
  1. Gunakan kata kunci go dan nama fungsi
func myFunc() {
    //goroutine运行的代码
}

go myFunc()

Cara menghentikan goroutine

Menghentikan goroutine adalah masalah yang lebih rumit, kerana goroutine Tiada cara yang jelas untuk menamatkan atau menjeda pada masa jalan. Ini kerana salah satu matlamat reka bentuk bahasa Go adalah untuk mengelakkan gorout daripada disekat semasa berjalan, jadi kami memerlukan beberapa teknik khas untuk menghentikannya.

Dalam bahasa Go, kami mempunyai empat cara berikut untuk menghentikan goroutine:

1 Menggunakan saluran

Menggunakan saluran ialah cara paling mudah dan selamat untuk menghentikan goroutine. Kita boleh mencipta saluran jenis bool Apabila kita perlu menghentikan goroutine, kita menghantar isyarat ke saluran ini.

func worker(stopChan chan bool) {
    for {
        select {
        case <-stopChan:
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    stopChan := make(chan bool)
    go worker(stopChan)
    time.Sleep(3 * time.Second)
    stopChan <- true
    time.Sleep(time.Second)
}
2. Menggunakan konteks

Dalam Go1.7, pakej konteks telah ditambahkan pada perpustakaan standard, menyediakan kaedah baharu untuk menggantung dan membatalkan goroutin. Kita boleh menghantar parameter Konteks dalam setiap goroutine, dan kemudian melakukan operasi batal pada pembolehubah Konteks ini apabila kita perlu menghentikan goroutine.

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("worker stopped")
            return
        default:
            fmt.Println("worker is running")
            time.Sleep(time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    go worker(ctx)
    time.Sleep(3 * time.Second)
    cancel()
    time.Sleep(time.Second)
}
3. Gunakan Mutex dan WaitGroup

untuk mengawal pemberhentian goroutine melalui pembolehubah kongsi Kaedah ini memerlukan penggunaan Mutex dan WaitGroup dalam pakej penyegerakan. Mutex digunakan untuk melindungi pembacaan dan penulisan pembolehubah yang dikongsi, dan WaitGroup digunakan untuk menunggu semua goroutine selesai.

var wg sync.WaitGroup
var stop bool
var mutex sync.Mutex

func worker() {
    defer wg.Done()
    for {
        mutex.Lock()
        if stop {
            mutex.Unlock()
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        mutex.Unlock()
        time.Sleep(time.Second)
    }
}

func main() {
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go worker()
    }
    time.Sleep(3 * time.Second)
    mutex.Lock()
    stop = true
    mutex.Unlock()
    wg.Wait()
    time.Sleep(time.Second)
}
4 Gunakan pakej runtime

Kaedah menggunakan pakej runtime sedikit lebih menyusahkan dalam kod yang menjalankan goroutine, anda perlu menyemak pembolehubah global dengan kerap. dan kemudian hentikan goroutine apabila anda perlu Apabila, gunakan fungsi dalam pakej runtime untuk memaksanya ditamatkan.

var stop bool

func worker() {
    for {
        if stop {
            fmt.Println("worker stopped")
            return
        }
        fmt.Println("worker is running")
        time.Sleep(time.Second)
    }
}

func main() {
    go worker()
    time.Sleep(3 * time.Second)
    stop = true
    time.Sleep(time.Second)
    runtime.Goexit() //退出当前运行的goroutine
}

Ringkasan

Menggunakan goroutine boleh meningkatkan prestasi serentak program, tetapi mengawal operasi goroutine juga amat penting Cara menghentikan goroutine dengan anggun telah menjadi sesuatu yang mesti kita hadapi masalah . Empat kaedah di atas mempunyai kelebihan tersendiri dan senario yang boleh digunakan, dan anda perlu memilih kaedah yang paling sesuai mengikut situasi tertentu.

Atas ialah kandungan terperinci Bagaimana untuk menghentikan goroutine dalam golang (empat kaedah). 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