อ่านจาก goroutine ช่องโดยไม่มีการปิดกั้น

0

คำถาม

ฉันมีสอง goroutines:หลัก worker และเป็น helper นั่นมันการหมุนไปสำหรับความช่วยเหลือบางอย่าง helper ได้พวกเกิดข้อผิดพลาดดังนั้นฉันใช้เป็นช่องสื่อสารผิดพลาดจากการ helper ไปที่ worker.

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

ที่นี่เป็นยังไง helper() เป็นชื่อ:

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

คำถาม:

  • เป็นคำให้การ err := <- c บล็อกเขาก็บล็อก worker? ฉันไม่คิดอย่างนั้นตั้งแต่ที่ช่อง buffered.

  • ถ้ามันเป็นการปิดกั้นจะทำยังไงให้มันไม่ใช่การปิดกั้น? ของฉันสำคัญที่สุคือต้องมี worker และมันโทรบอกต่อไปด้วยเหลือของทำงานโดยไม่ รออยู่ สำหรับค่าที่จะปรากฎบนช่อง

ขอบคุณ

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

คำตอบที่ดีที่สุด

2

คุณสามารถอย่างง่ายดายตรวจสอบ

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()
}

Q:คือการ err:=<-c จอดปิดทางงาน? ฉันไม่คิดอย่างนั้นตั้งแต่ที่ช่อง buffered.

เป็น: err := <- c จะปิดงาน

Q ถ้ามันเป็นการปิดกั้นจะทำยังไงให้มันไม่ใช่การปิดกั้น? ของฉันสำคัญที่สุคือต้องมีคนงานและมันโทรบอกต่อไปด้วยเหลือของทำงานโดยไม่รออยู่สำหรับค่าที่จะปรากฎบนช่อง

เป็น: หากคุณไม่ต้องการการปิดกั้นแค่ลบ err := <-c. ถ้าคุณต้องการ err ที่สุดเพิ่งย้าย err := <-c ไปจนถึงจุดจบ

คุณไม่สามารถอ่านช่องโดยไม่มีการปิดกั้นถ้าคุณผ่านไปโดยไม่มีการปิดกั้นสามารถได้ไม่มากไปกประมวลผลดรหัสนี้,เว้นแต่ว่ารหัสของคุณอยู่ในเรื่อยๆ

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

และคุณเคยเห็น errgroup หรือ waitgroup?

มันใช้อะตอมยกเลิกกับคอนเท็กซ์ข sync.ครั้งเดียวที่จะรับคำสั่งเข้าใจเรื่องนี้

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

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

หรือคุณสามารถใช้มันไปคุณ func แล้วจากนั้นก็รอให้เกิดข้อผิดพลาดในสถานที่ที่คุณต้องการ

2021-12-01 21:31:34
1

ในของคุณรหัสที่เหลือของงานอิสระของหรือไม่ช่วยพบมาเป็นข้อผิดพลาด คุณสามารถเพียงรับมาจากช่องหลังจากที่เหลือของที่ทำงานเสร็จสมบูรณ์@info:status

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

งั้นคงไม่ทำงาน()จะถูกบล็อคจนกระทั่งเป็นค่าปรากฎอยู่ c?
Someone

แล้วก็ฉันแค่ได้แก้ไข worker(). มันจะคืนค่ากลับมาเป็นข้อผิดพลาด/nil ต้องโทรบอก. ดังนั้นจะปฏิบัติการนี้จะถูกบล็อค?
Someone

ใช่มันพิเศษจะปฏิบัติการบล็อคจนกว่าช่วยส่งข้อ error หรือ nil ต้องช่อง แต่งานโดนล็อคเดียวที่หลังมันเสร็จสมบูรณ์ทั้งหมดทำงาน
Chandra Sekar

แต่ว่าช่วงตึกของคนโทรบอก worker. มีวิธีที่จะทำให้มันไม่ใช่การปิดกั้น?
Someone

ถ้าคนงานแล้วดังนั้นมันโทรบอกไม่ไม่เดี๋ยวก่อนเพื่อช่วยทำงานให้เสร็จสมบูรณ์ได้ยังไงมันกลับไปที่เกิดข้อผิดพลาดจากช่วยทำงาน?
Chandra Sekar
0

ฉันคิดว่าคุณต้องการรหัส..

รหัส

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

คุณสามารถอธิบายโดยทางของการแก้ไขนี้คำตอบแล้วทำไมนี่ถึงช่วยมั้ย? ฉันสงสัยว่าถ้านั่นจะเป็นประโยชน์ถ้าไม่ใช่เพื่อคำถามผู้เขียนเพื่ออนาคตเครื่องอ่าน.
halfer

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

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

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่