


Cara membatalkan kerja saluran berdasarkan ID dalam golang
Di golang, membatalkan kerja saluran adalah keperluan biasa. Apabila kita berurusan dengan tugasan serentak, kadangkala kita perlu membatalkan tugas pelaksanaan berdasarkan ID tugas. Jadi, bagaimana untuk melaksanakan fungsi ini dalam golang? Di bawah, saya akan memperkenalkan anda kepada kaedah yang mudah dan berkesan. Pertama, kita perlu mencipta saluran penimbal untuk menyimpan ID tugasan. Kami kemudiannya boleh menggunakan pernyataan pilih untuk mendengar operasi bacaan saluran dan menghantar ID tugasan ke saluran apabila tugasan perlu dibatalkan. Kemudian, dalam fungsi pelaksanaan tugas, kita boleh menentukan sama ada tugas itu perlu dibatalkan dengan menilai sama ada saluran ditutup. Jika saluran ditutup, tugas itu telah dibatalkan dan kami boleh menamatkan pelaksanaan tugas di tempat yang sesuai. Dengan cara ini, kami boleh membatalkan kerja saluran dengan mudah berdasarkan ID dalam golang. Di atas adalah kaedah yang diperkenalkan oleh editor php Xinyi, saya harap ia akan membantu semua orang!
Kandungan soalan
Jadi saya ada satu post
端点,它创建一个作业并将它们添加到一个 chan 中。 workerjobschan = make(chan job, maxqueuesize)
Beginilah saya melakukan tugas saya di saluran (main.go
):
for i := 1; i <= maxworkers; i++ { go func(i int) { for job := range workerjobschan { ctx, cancel := context.withcancel(context.background()) storejob(job.search.id, cancel) job.execute(ctx, c.db, i) } }(i) }
Saya menyimpan fungsi pembatalan dalam peta: canceljobfuncs = make(map[int]context.cancelfunc)
.
Ini adalah fungsi kerja:
func (j *job) execute(ctx context.context, db *sql.db, workerid int) error { for { select { // check for cancellation signal case <-ctx.done(): if err := ctx.err(); err != nil { fmt.println("worker", workerid, "error", err) } fmt.println("worker", workerid, "cancelled") return nil default: fmt.printf("worker%d: processing %s\n", workerid, j.search.query) time.sleep(2 * time.second) fmt.printf("worker%d: active %s\n", workerid, j.search.query) time.sleep(5 * time.second) fmt.printf("worker%d: completed %s!\n", workerid, j.search.query) } } }
Saya membatalkan konteks (dalam pengendali http) seperti ini:
cancelJob(search.ID)
Tetapi kerja tetap berjalan. Saya telah mencuba banyak perkara tetapi nampaknya tidak berjaya.
Penyelesaian
Berikut ialah cara untuk menggambarkan perkara yang jelas: jika kod anda tidak menyemak ctx.done()
, ia tidak mempunyai cara untuk mengetahui bahawa ia telah dibatalkan.
(BTW, ini adalah satu lagi parafrasa tentang apa yang @jimb tulis dalam ulasan untuk soalan anda).
Jadi apabila kod dalam kaedah .execute(...)
mula melaksanakan blok ini:
fmt.printf("worker%d: processing %s\n", workerid, j.search.query) time.sleep(2 * time.second) fmt.printf("worker%d: active %s\n", workerid, j.search.query) time.sleep(5 * time.second) fmt.printf("worker%d: completed %s!\n", workerid, j.search.query)
Ia akan sampai ke penghujung blok (7 saat). Tiada arahan yang menyuruhnya berhenti pada pembatalan.
Jika anda mahu fungsi anda dapat mengesan pembatalan semasa arahan "tidur", anda perlu menukar kod anda.
Berikut ialah contoh cara melakukan ini menggunakan contoh anda:
func (j *job) execute(ctx context.context, db *sql.db, workerid int) error { for { fmt.printf("worker%d: processing %s\n", workerid, j.search.query) // rewrite time.sleep() with time.after() so that it can be composed // in a select statement: select { case <-ctx.done(): fmt.println("worker", workerid, "cancelled") return nil case <-time.after(2 * time.second): // keep going } fmt.printf("worker%d: active %s\n", workerid, j.search.query) select { case <-ctx.done(): fmt.println("worker", workerid, "cancelled") return nil case <-time.after(5 * time.second): // keep going } fmt.printf("worker%d: completed %s!\n", workerid, j.search.query) } }
https://www.php.cn/link/3bc31a430954d8326605fc690ed22f4d
Saya rasa kod sebenar anda tidak mempunyai time.sleep()
指令,而是 processsearch(...)
或 doquery(...)
atau ...
Jika anda memerlukan fungsi ini boleh dibatalkan semasa pelaksanaan, anda perlu menyerahkan konteks pembatalan kepada mereka entah bagaimana dan minta mereka menyemak pembatalan dalam beberapa cara.
Salah satu cara untuk "lulus konteks" jelas sekali dengan menambahkannya pada parameter fungsi tersebut:
processsearch(ctx, ...) doquery(ctx, ...)
Tetapi bergantung pada kod sedia ada anda, sesetengah parameter mungkin sudah mempunyai kaedah terbina dalam untuk membatalkan.
Contohnya:
// an http.Request carries a context: func doQuery(req *http.Request, ....) { ... } // at call site: ... req := http.NewRequestWithContext(ctx, "GET", "https://some.other.service/", nil) doQuery(req, ...)
Atas ialah kandungan terperinci Cara membatalkan kerja saluran berdasarkan ID dalam golang. 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

AI Hentai Generator
Menjana ai hentai secara percuma.

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.

Artikel ini menerangkan cara menggunakan alat PPROF untuk menganalisis prestasi GO, termasuk membolehkan profil, mengumpul data, dan mengenal pasti kesesakan biasa seperti CPU dan isu memori.

Artikel ini membincangkan ujian unit menulis di GO, meliputi amalan terbaik, teknik mengejek, dan alat untuk pengurusan ujian yang cekap.

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, ...

Artikel ini membincangkan menguruskan kebergantungan modul Go melalui Go.Mod, meliputi spesifikasi, kemas kini, dan resolusi konflik. Ia menekankan amalan terbaik seperti versi semantik dan kemas kini biasa.

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
