Rumah > Artikel > pembangunan bahagian belakang > Mengapa program Go saya tidak menggunakan perpustakaan Konteks dengan betul?
Bahasa Go ialah bahasa pengaturcaraan yang sangat baik untuk pengaturcaraan serentak Penggunaan serentak program Go biasanya dilaksanakan menggunakan coroutine dan saluran. Dalam bahasa Go, pustaka Konteks digunakan secara meluas untuk mengawal kitaran hayat dan operasi pembatalan coroutine.
Walau bagaimanapun, kadangkala kami menghadapi beberapa masalah Sebagai contoh, program Go kami tidak boleh menggunakan perpustakaan Konteks dengan betul, menyebabkan program berjalan secara tidak normal. Jadi mengapa masalah sedemikian berlaku? Artikel ini akan memperkenalkan secara terperinci penggunaan pustaka Konteks dalam program Go dan sebab yang mungkin menyebabkan pustaka Konteks tidak digunakan dengan betul.
1. Apakah perpustakaan Konteks?
Pertama, kita perlu memahami apa itu perpustakaan Konteks. Pustaka Konteks ialah perpustakaan standard yang diperkenalkan oleh bahasa Go dalam versi 1.7 Ia digunakan untuk memindahkan maklumat konteks antara coroutine untuk mengawal tingkah laku coroutine semasa proses pemindahan. Pustaka Konteks digunakan terutamanya untuk mengawal kitaran hayat coroutine, menyampaikan rantaian skop permintaan, mengawal tamat masa dan operasi pembatalan, dan menyampaikan maklumat penjejakan dan log, dsb.
Apabila menggunakan Konteks, anda biasanya perlu mencipta objek Konteks akar, dan kemudian menggunakan objek ini untuk mencipta sub-Konteks, dengan itu membentuk struktur pokok Konteks. Dengan menggunakan objek Konteks dalam setiap coroutine, anda boleh mengawal coroutine. Jika anda ingin membatalkan coroutine, anda hanya perlu membatalkan objek Konteks coroutine yang sepadan.
2. Bagaimana hendak menggunakan perpustakaan Konteks?
Biasanya, penggunaan pustaka Konteks dibahagikan kepada langkah berikut:
Gunakan konteks.Latar Belakang() fungsi untuk mencipta Konteks akar:
ctx := context.Background()
Buat sub-Konteks melalui Konteks akar dan gunakan fungsi context.WithValue() untuk mencipta sub-Konteks:
ctx := context.Background() ctx2 := context.WithValue(ctx, key, value)
Antaranya, kunci dan nilai ialah kunci dan nilai masing-masing, digunakan untuk menyimpan dan memindahkan maklumat konteks.
Gunakan Konteks di dalam coroutine untuk mengawal tingkah laku coroutine. Contohnya:
func hello(ctx context.Context) { select { case <-ctx.Done(): return default: fmt.Println("Hello World!") } } func main() { ctx, cancel := context.WithCancel(context.Background()) go hello(ctx) time.Sleep(1 * time.Second) cancel() }
Dalam kod di atas, kami menggunakan fungsi context.WithCancel() untuk mencipta sub-Konteks dengan operasi pembatalan, dan kemudian hantar sub-Konteks ini kepada coroutine dalam fungsi hello() untuk kawalan. Dalam coroutine utama, gunakan fungsi cancel() untuk membatalkan Konteks yang sepadan, dengan itu menutup coroutine.
3. Masalah biasa dengan pustaka Konteks
Apabila menggunakan pustaka Konteks, kita mungkin menghadapi masalah biasa berikut:
func test(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("End") return default: fmt.Println("Run...") time.Sleep(1 * time.Second) } } } func main() { ctx, cancel := context.WithCancel(context.Background()) go test(ctx) fmt.Println("Start...") time.Sleep(3 * time.Second) cancel() fmt.Println("Cancel...") time.Sleep(3 * time.Second) fmt.Println("End...") }
Dalam kod di atas, kami menggunakan pernyataan gelung untuk terus mengeluarkan Run... dalam sub-coroutine, dan laksanakan cancel() dalam coroutine utama . Fungsi ini boleh menyebabkan sub-coroutine menamatkan output gelung. Walau bagaimanapun, apabila kami menetapkan tamat masa sebelum cancel(), seperti menggunakan:
go func() { time.Sleep(2 * time.Second) cancel() }()
, kod yang kami jangkakan ialah selepas 2 saat, sub-coroutine berhenti mengeluarkan Run..., dan kemudian mengeluarkan End , Kemudian, disebabkan oleh operasi tidur coroutine utama, program menunggu secara statik selama 3 saat, dan akhirnya mengeluarkan Tamat.. Tetapi sebenarnya, hasil output kod ini ialah:
Start... Run... Run... Cancel... End... Run... Run... Run...
Maksudnya, sub-coroutine tidak keluar dari gelung dalam masa, tetapi berhenti mengeluarkan Run... selepas menunggu selama 2 saat. Ini kerana selepas tamat masa pembatalan ditetapkan, coroutine utama mungkin tidak berpeluang untuk membatalkan subcoroutine selepas keluar, tetapi akan menunggu sehingga subcoroutine tamat dengan sendirinya atau semasa tempoh tamat masa sebelum keluar.
Cara untuk menyelesaikan masalah ini ialah dengan menggunakan penyata pilih untuk memantau panggilan pembatalan dan tamat masa secara serentak untuk memastikan sub-coroutine boleh dikeluarkan tepat pada masanya.
Apabila Konteks memindahkan maklumat konteks, kami biasanya menggunakan pasangan nilai kunci untuk memindahkannya, contohnya:
ctx := context.WithValue(context.Background(), "key", "value")
Walau bagaimanapun, apabila menggunakan Konteks untuk menghantar maklumat, maklumat sensitif mungkin dihantar ke bahagian lain coroutine, menyebabkan masalah kebocoran maklumat. Oleh itu, apabila menggunakan Konteks untuk memindahkan maklumat kontekstual, kita harus memberi perhatian khusus untuk melindungi maklumat sensitif untuk mengelakkan kebocoran maklumat.
4. Ringkasan
Ringkasnya, perpustakaan Konteks ialah perpustakaan standard yang sangat penting dalam bahasa Go Ia digunakan untuk memindahkan maklumat konteks antara coroutine untuk memudahkan pengurusan coroutine terkawal. Apabila menggunakan perpustakaan Konteks, kita perlu memberi perhatian kepada cara Konteks dicipta dan digunakan, terutamanya apabila keluar dari coroutine dan menghantar maklumat konteks Kita mesti memberi perhatian untuk mengelakkan beberapa masalah biasa, seperti kebocoran maklumat. Hanya dengan cara ini kita boleh menggunakan perpustakaan Konteks dengan betul dan berkesan dalam program Go.
Atas ialah kandungan terperinci Mengapa program Go saya tidak menggunakan perpustakaan Konteks dengan betul?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!