Bir goroutine kanalından engellemeden okuma

0

Soru

İki goroutinim var: ana worker ve bir helper biraz yardım için döndüğünü. helper hatalarla karşılaşabilirim, bu yüzden hataları iletmek için bir kanal kullanıyorum helper to the worker.

func helper(c chan <- error) (){
    //do some work
    c <- err // send errors/nil on c
}

İşte nasıl helper() denir:

func worker() error {
    //do some work
    c := make(chan error, 1)
    go helper(c)
    err := <- c
    return err
}

Sorular:

  • Bu bir ifade mi err := <- c engelleyici worker? Kanal tamponlu olduğu için sanmıyorum.

  • Engelliyorsa, engellememesini nasıl sağlayabilirim? Benim şartım worker ve arayan, değerin kanalda görünmesini beklemeden işin geri kalanıyla devam eder.

Teşekkürler.

channel go goroutine
2021-11-24 01:59:57
3

En iyi cevabı

2

Kolayca doğrulayabilirsiniz

func helper(c chan<- error) {
    time.Sleep(5 * time.Second)
    c <- errors.New("") // send errors/nil on c
}

func worker() error {
    fmt.Println("do one")

    c := make(chan error, 1)
    go helper(c)

    err := <-c
    fmt.Println("do two")

    return err
}

func main() {
    worker()
}

S: İfade err mi: = Kanal tamponlu olduğu için sanmıyorum.

Bir: err := <- c işçiyi engeller.

S: Engelliyorsa, engellememesini nasıl sağlayabilirim? Benim gereksinimim, işçinin ve arayanın, değerin kanalda görünmesini beklemeden işin geri kalanıyla devam etmesini sağlamaktır.

A: engelleme istemiyorsanız, sadece kaldırın err := <-c. Sonunda bir hataya ihtiyacınız varsa, sadece hareket edin err := <-c sonuna kadar.

Engellemeden kanalı okuyamazsınız, engellemeden geçerseniz, kodunuz bir döngü içinde olmadıkça artık bu kodu yürütemezsiniz.

Loop:
    for {
        select {
        case <-c:
            break Loop
        default:
            //default will go through without blocking
        }
        // do something
    }

Ve hiç errgroup veya waitgroup gördünüz mü?

Atomik kullanır, bağlamı iptal eder ve senkronize eder.Bunu uygulamak için bir kez.

https://github.com/golang/sync/blob/master/errgroup/errgroup.go

https://github.com/golang/go/blob/master/src/sync/waitgroup.go

Ya da sadece kullanabilirsiniz, size func gidin ve sonra istediğiniz herhangi bir yerde hata için bekleyin.

2021-12-01 21:31:34
1

Kodunuzda, işin geri kalanı, yardımcının bir hatayla karşılaşıp karşılaşmadığından bağımsızdır. İşin geri kalanı tamamlandıktan sonra kanaldan kolayca alabilirsiniz.

func worker() error {
    //do some work
    c := make(chan error, 1)
    go helper(c)
    //do rest of the work
    return <-c
}
2021-11-24 02:54:28

Peki, bir değer görünene kadar worker() engellenmez mi c?
Someone

Ayrıca, yeni düzenledim worker(). Arayana error/nil değerini döndürür. Bu işlem, bloke olur?
Someone

Evet, helper gönderene kadar bu özel işlem engellenir error veya nil bu kanal için. Ancak işçi ancak tüm çalışmalarını tamamladıktan sonra engellenir.
Chandra Sekar

Ama bu arayanı engeller. worker. Engellememenin bir yolu var mı?
Someone

Worker ve dolayısıyla arayanı helper'ın tamamlanmasını beklemiyorsa, hatayı helper'dan nasıl döndürebilir?
Chandra Sekar
0

Bence bu koda ihtiyacın var..

bu kodu çalıştır

package main

import (
    "log"
    "sync"
)

func helper(c chan<- error) {

    for {
        var err error = nil
        // do job

        if err != nil {
            c <- err // send errors/nil on c
            break
        }
    }

}

func worker(c chan error) error {
    log.Println("first log")

    go func() {
        helper(c)
    }()

    count := 1
    Loop:
        for {
            select {
            case err := <- c :
                return err
            default:
                log.Println(count, " log")
                count++
                isFinished := false
                // do your job
                if isFinished {
                    break Loop // remove this when you test

                }
            }
        }
    return nil
}

func main() {
    wg := sync.WaitGroup{}
    wg.Add(1)
    go func() {
        c := make(chan error, 1)
        worker(c)
        wg.Done()
    }()
    wg.Wait()
}
2021-11-24 02:35:53

- Ebilmek sen açıklamak, arada bir düzen için bu cevap, neden bu yardım? Bunun, soru yazarı için olmasa da, gelecekteki okuyucular için yararlı olup olmayacağını merak ediyorum.
halfer

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................