Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
终止第二个goroutine_Go - Fatal编程技术网

终止第二个goroutine

终止第二个goroutine,go,Go,我有以下代码片段 package main import ( "errors" "fmt" "time" ) func errName(ch chan error) { for i := 0; i < 10000; i++ { } ch <- errors.New("Error name") close(ch) } func errEmail(ch chan error) { for i := 0; i &

我有以下代码片段

package main

import (
    "errors"
    "fmt"
    "time"
)

func errName(ch chan error) {

    for i := 0; i < 10000; i++ {

    }

    ch <- errors.New("Error name")
    close(ch)
}

func errEmail(ch chan error) {

    for i := 0; i < 100; i++ {

    }
    ch <- errors.New("Error email")
    close(ch)
}

func main() {

    ch := make(chan error)

    go errName(ch)
    go errEmail(ch)
    fmt.Println(<-ch)
    //close(ch)

    time.Sleep(1000000)

}
我知道,当我删除close语句时,它不会惊慌,但正在运行的goroutine上的通道仍在等待错误引用,这意味着,它白白浪费了内存(等待)


当其中一个向通道发送错误时,我将不再关心第二个错误,这是我的目标。

使用另一个通道发送完成信号:

package main

import (
    "errors"
    "fmt"
    "time"
)

func errName(ch chan error, done chan struct{}) {
    for i := 0; i < 10000; i++ {
        select {
        case <-done:
            fmt.Println("early return from name")
            return
        default:
        }
    }
    select {
    case: ch <- errors.New("Error name")
    default:
    }
}

func errEmail(ch chan error, done chan struct{}) {
    for i := 0; i < 100; i++ {
        select {
        case <-done:
            fmt.Println("early return from email")
            return
        default:
        }
    }
    select {
    case ch <- errors.New("Error email"):
    default:
    }
}

func main() {
    ch := make(chan error, 1)
    done := make(chan struct{})
    go errName(ch, done)
    go errEmail(ch, done)
    fmt.Println(<-ch)
    close(done)
    time.Sleep(1000000)
}
主程序包
进口(
“错误”
“fmt”
“时间”
)
func errName(ch chan error,done chan struct{}){
对于i:=0;i<10000;i++{
挑选{

案例使用另一个通道发送信号完成:

package main

import (
    "errors"
    "fmt"
    "time"
)

func errName(ch chan error, done chan struct{}) {
    for i := 0; i < 10000; i++ {
        select {
        case <-done:
            fmt.Println("early return from name")
            return
        default:
        }
    }
    select {
    case: ch <- errors.New("Error name")
    default:
    }
}

func errEmail(ch chan error, done chan struct{}) {
    for i := 0; i < 100; i++ {
        select {
        case <-done:
            fmt.Println("early return from email")
            return
        default:
        }
    }
    select {
    case ch <- errors.New("Error email"):
    default:
    }
}

func main() {
    ch := make(chan error, 1)
    done := make(chan struct{})
    go errName(ch, done)
    go errEmail(ch, done)
    fmt.Println(<-ch)
    close(done)
    time.Sleep(1000000)
}
主程序包
进口(
“错误”
“fmt”
“时间”
)
func errName(ch chan error,done chan struct{}){
对于i:=0;i<10000;i++{
挑选{

案例组织这种行为的标准方法是使用

package main

import (
    "fmt"
    "time"

    "code.google.com/p/go.net/context"
)

func errName(ctx context.Context, cancel context.CancelFunc) {
    for i := 0; i < 10000; i++ {
        select {
        case <-ctx.Done():
            return
        default:
        }
    }
    cancel()
}

func errEmail(ctx context.Context, cancel context.CancelFunc) {

    for i := 0; i < 100; i++ {
        select {
        case <-ctx.Done():
            return
        default:
        }
    }
    cancel()
}

func main() {

    ctx := context.Background()

    ctx, cancel := context.WithCancel(ctx)

    go errName(ctx, cancel)
    go errEmail(ctx, cancel)

    <-ctx.Done()

    if ctx.Err() != nil {
        fmt.Println(ctx.Err())
    }

    time.Sleep(1000000)

}
主程序包
进口(
“fmt”
“时间”
“code.google.com/p/go.net/context”
)
func errName(ctx context.context,cancel context.CancelFunc){
对于i:=0;i<10000;i++{
挑选{

案例组织这种行为的标准方法是使用

package main

import (
    "fmt"
    "time"

    "code.google.com/p/go.net/context"
)

func errName(ctx context.Context, cancel context.CancelFunc) {
    for i := 0; i < 10000; i++ {
        select {
        case <-ctx.Done():
            return
        default:
        }
    }
    cancel()
}

func errEmail(ctx context.Context, cancel context.CancelFunc) {

    for i := 0; i < 100; i++ {
        select {
        case <-ctx.Done():
            return
        default:
        }
    }
    cancel()
}

func main() {

    ctx := context.Background()

    ctx, cancel := context.WithCancel(ctx)

    go errName(ctx, cancel)
    go errEmail(ctx, cancel)

    <-ctx.Done()

    if ctx.Err() != nil {
        fmt.Println(ctx.Err())
    }

    time.Sleep(1000000)

}
主程序包
进口(
“fmt”
“时间”
“code.google.com/p/go.net/context”
)
func errName(ctx context.context,cancel context.CancelFunc){
对于i:=0;i<10000;i++{
挑选{

提到的case
Done-chan-struct{}
(或其
context.context
化身)是惯用的和真实的行为方式。但是避免代码片段中出现恐慌的简单方法是

import "sync"

var once sync.Once

func errName(ch chan error) {
    for i := 0; i < 10000; i++ {

    }
    once.Do(func() {ch <- errors.New("Error name"); close(ch)}())
}
func errName(ch chan error) {
    for i := 0; i < 10000; i++ {

    }
    once.Do(func() {ch <- errors.New("Error name"); close(ch)}())
 }
导入“同步”
一次同步
func errName(ch chan错误){
对于i:=0;i<10000;i++{
}

曾经提到的once.Do(func(){ch
Done-chan-struct{}
(或其
context.context
的化身)是惯用的和真实的行为方式。但是避免代码片段中出现恐慌的简单方法是

import "sync"

var once sync.Once

func errName(ch chan error) {
    for i := 0; i < 10000; i++ {

    }
    once.Do(func() {ch <- errors.New("Error name"); close(ch)}())
}
func errName(ch chan error) {
    for i := 0; i < 10000; i++ {

    }
    once.Do(func() {ch <- errors.New("Error name"); close(ch)}())
 }
导入“同步”
一次同步
func errName(ch chan错误){
对于i:=0;i<10000;i++{
}

once.Do(func(){ch我读过这些文章,但我不知道如何使用它。例如,谢谢,我将尝试使用它。我不理解select语句,语句
select
是一个基本操作。有关详细信息,请阅读并发教程。例如:。您还可以听一个对话:这是通过在频道上轮询进行取消。无法“立即”取消/中止goroutine。我读过这些文章,但不知道如何使用它。例如,谢谢,我将尝试使用它。我不理解select语句,语句
select
是一个基本操作。有关详细信息,请阅读并发教程。例如:。您也可以听一个对话:这是通过在频道上轮询进行取消。下面的re不是“立即”取消/中止goroutine的方法。