


Mengapakah kebuntuan berlaku apabila panggilan fungsi yang mengisi saluran tidak dibenamkan dalam Goroutine?
Apabila panggilan fungsi yang mengisi saluran tidak dibenamkan dalam Goroutine, sebab kebuntuan berlaku adalah kerana operasi hantar dan terima saluran disekat. Jika fungsi yang mengisi saluran dipanggil dalam Goroutine utama, dan operasi pengisian tidak dimasukkan ke dalam Goroutine baharu untuk dijalankan di dalam fungsi, maka Goroutine utama akan menunggu saluran mempunyai ruang yang cukup untuk menerima data, dan operasi mengisi tidak dapat dilakukan, dengan itu Membawa kepada kebuntuan. Oleh itu, untuk mengelakkan kebuntuan, kita perlu menggunakan Goroutine untuk pelaksanaan serentak dalam operasi mengisi saluran bagi memastikan operasi pengisian dan operasi penerimaan dapat dilakukan pada masa yang sama.
Kandungan soalan
Saya tahu tentang pilihan sync
包及其 waitgroup
dan saya tidak mahu menggunakannya untuk ujian ini. Saya sedang menguji semafor.
Jadi saya ada:
package main import ( "fmt" "os" "time" ) func main() { fmt.print("wassap") jobs := make(chan int) processstarted := make(chan struct{}, 1) processcompleted := make(chan struct{}, 1) createjobs(jobs) go func() { worker(jobs, processstarted, processcompleted) }() go func() { sync(processstarted, processcompleted) }() time.sleep(3600 * time.second) fmt.print("\nend of main...") interrupt := make(chan os.signal) <-interrupt } func createjobs(jobs chan<- int) { defer close(jobs) for i := 1; i < 20; i++ { jobs <- i } } func worker(jobs <-chan int, processstarted <-chan struct{}, processcompleted <-chan struct{}) { for { select { case i := <-jobs: fmt.printf("\nfetching job #%d from channel", i) time.sleep(2 * time.second) case <-processstarted: fmt.print("\nprocess started. waiting for it to be completed") <-processcompleted fmt.print("\nprocess completed") } } } func sync(processstarted chan<- struct{}, processcompleted chan<- struct{}) { // acquire semaphore. send signal to channel to indicate that it is busy processstarted <- struct{}{} for i := 1; i < 5; i++ { fmt.printf("\nprocessing %d", i) time.sleep(5 * time.second) } // release semaphore processcompleted <- struct{}{} }
Apa yang saya ingin uji adalah sangat mudah: Saya mempunyai createjobs
函数,其唯一目的是将元素添加到通道,在本例中是一个 int 通道。然后我有一个 worker
yang akan mengekstrak objek dari saluran itu dan tidur selama 2 saat sebelum mengekstrak elemen seterusnya.
Kini, terdapat juga fungsi penyegerakan. Satu-satunya tujuan fungsi ini adalah untuk mensimulasikan elemen worker
运行时启动的进程。如果此进程处于活动状态,则在 sync
结束时应停止处理 jobs
, itulah sebabnya saya mempunyai dua saluran, satu menunjukkan bahawa proses telah dimulakan dan satu lagi bahawa proses telah tamat.
Saya mendapat ralat berikut semasa menjalankan kod saya:
fatal error: all goroutines are asleep - deadlock!
Jika saya mengubah suai cara createjobs
dipanggil, bungkusnya dalam goroutine seperti ini:
go func() { createJobs(jobs) }()
Kemudian kod saya berjalan dengan betul.
Saya cuma nak faham kenapa ini berlaku. Apa yang saya maksudkan ialah: rutin main
sedang dilaksanakan dan kemudian ia memanggil main
例程正在执行,然后它调用 createjobs
(无换行),因此 main
例程应该被阻止,直到此调用结束。一旦 createjobs
结束,就说明通道中有元素了。 main
继续执行并启动其他 goroutine worker
和 sync
来完成它们的工作。在 main
(tanpa baris baharu), jadi rutin main
harus disekat sehingga panggilan ini tamat. Sebaik sahaja
utama
meneruskan pelaksanaan dan memulakan gorout lain pekerja
dan sync
untuk menyelesaikan kerja mereka. Sebelum utama
tamat, saya hanya menambah sleeper untuk memberi masa goroutine yang dibuat sebelum ini untuk disiapkan.
createjobs
发生在 goroutine 之外时会发生什么。
解决方法
您将 jobs
声明为无缓冲通道,然后尝试将 20 个值同步推入其中。当您调用 createjobs(jobs)
Saya tidak meminta penyelesaian lain untuk masalah ini, saya cuma ingin tahu apa yang berlaku apabila
pekerjaan
sebagai saluran yang tidak ditimbal dan kemudian cuba menolak 20 nilai ke dalamnya secara serentak. Ini akan menyekat fungsi utama anda apabila anda memanggil . Tukar baris 13 kepada:
jobs := make(chan int, 20)
...akan menyelesaikan kebuntuan.
EDIT - Penjelasan diminta dalam ulasan:createjobs(jobs)
Satu analogi yang baik untuk saluran yang tidak dibuffer ialah paip, dalam kes ini prosesnya kelihatan seperti ini:
+------------------+ +------------+ +-------------+ | PRODUCER | | PIPE | | CONSUMER | | +---->| +----->| | | createJobs(jobs) | | unbuffered | | worker(...) | | | | channel | | | +------------------+ +------------+ +-------------+
dipanggil serentak dan belum ada pengguna yang sedang berjalan.
main()
Atas ialah kandungan terperinci Mengapakah kebuntuan berlaku apabila panggilan fungsi yang mengisi saluran tidak dibenamkan dalam Goroutine?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

OpenSSL, sebagai perpustakaan sumber terbuka yang digunakan secara meluas dalam komunikasi yang selamat, menyediakan algoritma penyulitan, kunci dan fungsi pengurusan sijil. Walau bagaimanapun, terdapat beberapa kelemahan keselamatan yang diketahui dalam versi sejarahnya, yang sebahagiannya sangat berbahaya. Artikel ini akan memberi tumpuan kepada kelemahan umum dan langkah -langkah tindak balas untuk OpenSSL dalam sistem Debian. Debianopenssl yang dikenal pasti: OpenSSL telah mengalami beberapa kelemahan yang serius, seperti: Kerentanan Pendarahan Jantung (CVE-2014-0160): Kelemahan ini mempengaruhi OpenSSL 1.0.1 hingga 1.0.1f dan 1.0.2 hingga 1.0.2 versi beta. Penyerang boleh menggunakan kelemahan ini untuk maklumat sensitif baca yang tidak dibenarkan di pelayan, termasuk kunci penyulitan, dll.

Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Laluan Pembelajaran Backend: Perjalanan Eksplorasi dari Front-End ke Back-End sebagai pemula back-end yang berubah dari pembangunan front-end, anda sudah mempunyai asas Nodejs, ...

Perbezaan antara percetakan rentetan dalam bahasa Go: perbezaan kesan menggunakan fungsi println dan rentetan () sedang ...

Di bawah rangka kerja beegoorm, bagaimana untuk menentukan pangkalan data yang berkaitan dengan model? Banyak projek beego memerlukan pelbagai pangkalan data untuk dikendalikan secara serentak. Semasa menggunakan beego ...

Masalah menggunakan redisstream untuk melaksanakan beratur mesej dalam bahasa Go menggunakan bahasa Go dan redis ...

Artikel ini memperkenalkan pelbagai kaedah dan alat untuk memantau pangkalan data PostgreSQL di bawah sistem Debian, membantu anda memahami pemantauan prestasi pangkalan data sepenuhnya. 1. Gunakan PostgreSQL untuk membina pemantauan PostgreSQL sendiri menyediakan pelbagai pandangan untuk pemantauan aktiviti pangkalan data: PG_STAT_ACTIVITY: Memaparkan aktiviti pangkalan data dalam masa nyata, termasuk sambungan, pertanyaan, urus niaga dan maklumat lain. PG_STAT_REPLITI: Memantau status replikasi, terutamanya sesuai untuk kluster replikasi aliran. PG_STAT_DATABASE: Menyediakan statistik pangkalan data, seperti saiz pangkalan data, masa komitmen/masa rollback transaksi dan petunjuk utama lain. 2. Gunakan alat analisis log pgbadg
