Golang 通道输入输出学习(同刚上手的小新手)

发布时间:2024年01月16日

Golang 通道的特点为以下几点:

1、如果是接收(RX)

1.1、如果通道是无缓冲的,接收操作只有在有其他 goroutine 发送数据到通道时才会成功,否则会阻塞。
1.2、如果通道是有缓冲的,接收操作只有在通道缓冲区有数据时才会成功,否则会阻塞。

2、如果是写入(TX)

2.1、如果通道是无缓冲的(即容量为0),发送操作会阻塞直到有其他 goroutine 准备好接收这个数据。

2.2、如果通道是有缓冲的(即容量大于0),发送操作只有在通道缓冲区已满时才会阻塞,否则会立即完成。

了解 TAP(基于任务模式的异步编程模型)的同学很容易理解这套模型。

Golang 像 C/C++ 20、C# 4.5 语言之中,我们需要在另一个协同程序之中等待某个 “stackless 无栈协同子程序” 的输出结果。

以 Microsoft Virual C# 为例子:

TaskCompletionSource.SetResult() // 管道输入

await?TaskCompletionSource.Task

TaskCompletionSource.Task.Result // 管道输出

它们其实都差不多的,只是 C# 的实现,代码会多点,C/C++ 会更多点,但大家都可以实现,但比 Golang 会繁琐很多,但其优点是更为可控(这点在大型且复杂的项目之中很重要)。

只是区别是输入这部分,其它语言并未提供类似的机制,但我们可以通过在调用协同程序的时候传入特定参数来表示输入,但如果需要模拟这套机制并不复杂,如模拟管道读入。

我们只需要使用 AutoResetEvent 进行同步即可轻松实现,当然如果要考虑TX/RX缓冲区,从实现上来说这个也并不复杂。

在 Golang 之中,永久阻塞协程,可以执行该条命令:

?<-make(chan struct{})

其作用为等待空白 chan 的输出,但由于没有任何地方可以向管道输入数据,所以会无限制阻塞该协同程序,当然写法上也不一定仅用该方法。

但这类代码执行,想要退出就只有一个办法,调用 os.Exit(exitCode) 命令关闭当前的进程才可以退出该协程的运行。

运算符:<-

在 Golang 之中向管道输入:

管道变量 <- 数据

在 Golang 之中向变量输出:

数据 <- 管道变量

本人对于 Golang 用起来不是太顺手,不太快乐,主要是以下几个点:

1、无原生指针(intptr,这个是无可奈何地办法)

2、语言规范要求太死,格式化四个空格捣鼓半天还是不成(制表符)

3、没有模板(泛型)

4、内存不可控制,.NET 可以显示GC回收及控制GC类型,Golang 是一点解决方案都无

5、没有析构函数

6、没有线程概念

我本人更喜欢?“多线程+协程” 全部可控,自行决定、评估合适采用协程,编程语言要提供最强的灵活性,但这或许在今时今日会是一个老古董的想法了。

7、过度依赖于IDE

例如:

过度的类型推导,Golang 之中可以大量的类型推导,即匿名变量声明,在vim、notepad++、sublime 等这些环境之中有时候真的会很困惑。

其它的不在此处累赘,每个语言都有其优点及适用场景,本文也不是来批评编程语言的,这没有意义,工具存在自然有其存在的意义,作为开发人员的我们,只需要那这些语言实现我们期望的一切即可,但也需要考量成本及多方因素。

就像我们可以用 C/C++ 解决现代计算机几乎所有的问题,如果我们使用 C/C++ 不可以解决,那么我们就可以写 .S、.ASM 或者内嵌汇编代码来解决问题,如果汇编也不能解决,那么这个问题就不是你我可以解决的,那么就交给其它人或者未来的人们去解决把。

不曾否认 Golang 语言的优点,简单,就是塔喵滴简单,在现代这个浮躁的中国大陆技术界,招募年轻人新鲜血液来说,Golang 这类型编程语言,显然更容易的多,大家都是一群草台班子,普通的人们,除了装X,一无是处。

一个或许未来会发生的现实,也许未来的新生代开发人员,在学校学习时,在也不会在接触汇编、再也不会接触 C 语言,Golang、Rust 这些语言成为教材上面,引领学生初步学习,乃至入门的编程语言,想想,也许,还挺可怕的。

package main

import (
	"fmt"
	"os"
	"os/signal"
)

func main() {
	stop := make(chan os.Signal, 1)
	signal.Notify(stop, os.Interrupt)

	signal := make(chan os.Signal, 1)
	go func() {
		fmt.Println("程序即将关闭...")

		// 在这里执行你的自定义操作
		fmt.Println("执行自定义操作完成")
		// os.Exit(0)

		signal <- <-stop
	}()

	fmt.Println("按下 Control+C 或关闭控制台窗口以退出程序")
	// <-make(chan struct{})

	fmt.Println("信号:", <-signal)
}

文章来源:https://blog.csdn.net/liulilittle/article/details/135619660
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。