Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Melaksanakan Penguncian dengan Tamat Masa dalam Go menggunakan Saluran?

Bagaimana untuk Melaksanakan Penguncian dengan Tamat Masa dalam Go menggunakan Saluran?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-10-31 00:31:29936semak imbas

How to Implement Locking with Timeouts in Go using Channels?

Mengunci dengan Tamat Masa dalam Go

Cabaran:

Mendapatkan kunci dalam Go boleh menjadi masalah, terutamanya apabila menangani kependaman -operasi sensitif. Antara muka penyegerakan.Mutex hanya menyediakan fungsi penguncian dan buka kunci asas tanpa keupayaan untuk memperoleh kunci secara bersyarat atau dalam jangka masa tertentu.

Penyelesaian:

Menggunakan Saluran sebagai Mutex:

Penyelesaian yang mudah dan berkesan ialah menggunakan saluran sebagai primitif pengecualian bersama. Dengan mencipta saluran dengan saiz penimbal satu, anda boleh mensimulasikan kunci:

<code class="go">l := make(chan struct{}, 1)</code>

Mengunci:

Untuk memperoleh kunci, hantar isyarat kepada saluran:

<code class="go">l <- struct{}{}</code>

Membuka kunci:

Untuk melepaskan kunci, terima daripada saluran:

<code class="go"><-l</code>

Cuba Kunci:

Untuk cuba mengunci dengan tamat masa, gunakan pernyataan pilih:

<code class="go">select {
case l <- struct{}{}:
    // lock acquired
    <-l
default:
    // lock not acquired
}</code>

Dengan menggabungkan pendekatan ini dengan masa.Selepas(), anda boleh melaksanakan TryLock dengan tarikh akhir:

<code class="go">select {
case l <- struct{}{}:
    // lock acquired
    <-l
case <-time.After(time.Minute):
    // lock not acquired
}</code>

Contoh 1: Mengehadkan Operasi Sensitif Latensi

<code class="go">func (s *RPCService) DoTheThing(ctx context.Context, ...) ... {
  if AcquireLock(ctx.Deadline(), &s.someObj[req.Parameter].lock) {
    defer ReleaseLock(&s.someObj[req.Parameter].lock)
    ... expensive computation ...
  } else {
    return s.cheapCachedResponse[req.Parameter]
  }
}</code>

Contoh 2: Mengemas kini Statistik dengan Tamat Masa

<code class="go">func (s *StatsObject) updateObjStats(key, value interface{}) {
  if AcquireLock(200*time.Millisecond, &s.someObj[key].lock) {
    defer ReleaseLock(&s.someObj[key].lock)
    ... update stats ...
    ... fill in s.cheapCachedResponse ...
  }
}

func (s *StatsObject) UpdateStats() {
  s.someObj.Range(s.updateObjStats)
}</code>

Pendekatan ini membolehkan anda memperoleh kunci secara bersyarat sambil turut mengendalikan masalah prestasi dan penggunaan sumber dengan berkesan.

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Penguncian dengan Tamat Masa dalam Go menggunakan Saluran?. 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