终止第二个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++{
挑选{
提到的caseDone-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(){chDone-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的方法。