Go程序设计语言翻译问题(goroutine)

中文:Go程序设计语言 2017.1
英文:The Go Programming Language 2016

8.4.2. Pipelines
8.4.2管道章节

在这里插入图片描述
修正:
第一个管道应该改成通道,cannel是概念词汇
重要概念词汇不能混淆
来自chatGPT3.5:
Go Pipelines和channel都是Go语言中用于实现并发编程的重要特性,但它们之间有一些区别。

首先,Go Pipelines是一种将多个阶段的处理连接在一起的方式,每个阶段都是一个goroutine,它们通过channel进行通信。Go Pipelines通常用于处理数据流,例如从文件或网络读取数据,对数据进行处理,然后将结果写回文件或网络。Go Pipelines的优点是可以将处理过程分解为多个阶段,每个阶段都可以并行执行,从而提高处理效率。

相比之下,channel是一种用于在goroutine之间进行通信的机制。通过channel,一个goroutine可以向另一个goroutine发送数据,也可以从另一个goroutine接收数据。channel的优点是可以实现goroutine之间的同步和通信,从而避免了共享内存带来的并发问题。

因此,Go Pipelines和channel都是Go语言中用于实现并发编程的重要特性,但它们的应用场景略有不同。Go Pipelines通常用于处理数据流,而channel则用于实现goroutine之间的同步和通信。

Go Pipelines通常包含多个goroutine和多个channel。在Go Pipelines中,每个阶段都是一个goroutine,它们通过channel进行通信。每个阶段通常会有一个输入channel和一个输出channel,用于接收上一阶段的输出和向下一阶段发送数据。因此,Go Pipelines通常包含多个goroutine和多个channel,它们协同工作以完成数据处理任务

在这里插入图片描述
修正:
删除“因为通道会满”(原文没有提及)
我个人不太喜欢这个简单的解释,
我的理解(参考chat):

  1. 如果放在主goroutine循环前,具体执行来说:
    当 for f := range filenames 循环开始执行时,它会从 filenames 通道中获取一个文件名,然后将该文件名发送到 jobs 通道中,表示需要处理该文件。然后,它会等待 worker goroutine 向 sizes 通道发送一个消息,表示该文件已经处理完毕。但是,由于 wg.Wait() 的计数器一直没有被归零(因为wg.Add(1)执行了),阻塞,worker goroutine 无法向 sizes 通道发送消息,因此 for f := range filenames 循环会一直等待下去,从而导致程序陷入死锁状态。

  2. 如果放在主goroutine循环后,因为如果没有go,sizes管道只能放入一个内容,而wg.Wait()会阻塞,导致无法执行到for size := range sizes(循环去除放入的管道内容),
    //此时被放入管道内容就一直没人拿出来,导致后面goroutine也一直放不进去,卡死
    补充下更详细的说明:

func makeThumbnails6(filenames <-chan string) int64 {
	sizes := make(chan int64)
	var wg sync.WaitGroup // number of working goroutines
	for f := range filenames {
		wg.Add(1) //必须在goroutine开始前调用,我们无法确保Add发送在close之前
		// worker
		go func(f string) {
			defer wg.Done() //使用defer来确保即使出现错误,计数器也会递减
			thumb, err := thumbnail.ImageFile(f)
			if err != nil {
				log.Println(err)
				return
			}
			info, _ := os.Stat(thumb) // OK to ignore error
			sizes <- info.Size()
		}(f)
	}

	//必须和上面的循环并发执行,否则会导致卡死,
	//因为如果没有go,sizes管道只能放入一个内容,而wg.Wait()会阻塞,导致无法执行到for size := range sizes(循环去除放入的管道内容),
	//此时被放入管道内容就一直没人拿出来,导致后面goroutine也一直放不进去,卡死
	go func() {
		wg.Wait() //阻塞当前的 goroutine 直到计数器被归零(当计数器减为 0 时,允许程序继续执行下去)
		close(sizes)
	}()

	var total int64
	// 这里不是循环sizes数组,是循环获取sizes的管道信息,每次goroutine执行完就会插入一个数据,循环就会进行读取
	for size := range sizes {
		total += size
	}
	return total
}

正确顺序:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值