当前位置: 首页 > news >正文

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

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

相关文章:

  • 01.16
  • 广告投放场景中ABtest分析的评价、优化和决策建议
  • vs2022配置OpenCV测试
  • 注意!不清楚这些,2024上半年软考别轻易尝试!
  • 【好书推荐-第四期】《Go专家编程(第2版)》华为资深技术专家力作,第1版评分9.4,适合Go程序员面试
  • 使用WAF防御网络上的隐蔽威胁之SQL注入攻击
  • Android项目架构怎么做
  • 大数据Doris(五十六):SQL函数之地理位置函数
  • WEB前端人机交互导论实验-实训9 JavaScript
  • 逸学Docker【java工程师基础】3.3Docker安装nacos
  • Golang 替换数字卡码54题
  • 【总结】浅谈深度学习算法与硬件协同优化
  • Git提交规范
  • ❤ HbuildX使用以及快捷键
  • 【深度学习:Synthetic Training Data 】合成训练数据简介
  • JavaScript 如何正确处理 Unicode 编码问题!
  • canvas绘制圆角头像
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • gcc介绍及安装
  • JavaScript实现分页效果
  • JS函数式编程 数组部分风格 ES6版
  • Python socket服务器端、客户端传送信息
  • Swoft 源码剖析 - 代码自动更新机制
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • yii2中session跨域名的问题
  • 阿里云应用高可用服务公测发布
  • 机器学习中为什么要做归一化normalization
  • 前端性能优化--懒加载和预加载
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #每天一道面试题# 什么是MySQL的回表查询
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (AngularJS)Angular 控制器之间通信初探
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (南京观海微电子)——I3C协议介绍
  • (原)Matlab的svmtrain和svmclassify
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)Windows2003安全设置/维护
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • ./configure,make,make install的作用(转)
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET下ASPX编程的几个小问题
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • @基于大模型的旅游路线推荐方案
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • []C/C++读取串口接收到的数据程序