如何在 golang 中显式发送 EOF 到 io.ReadCloser?
来源:stackoverflow
时间:2024-04-02 12:21:36 354浏览 收藏
最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《如何在 golang 中显式发送 EOF 到 io.ReadCloser?》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~
希望您身体健康地收到此消息。
所以我正在研究的 golang 程序中存在这个错误,代码库中的 stdcopy.stdcopy() 阻塞方法可能会导致所有内容挂起。出现此问题的原因是 docker 不断向 stdcopy 阻塞方法发送信息,而阻塞方法只有在向其发送 eof 时才能停止运行。 stdcopy 接受 readcloser 类型参数,这是阻塞方法从 docker 读取信息的方式。 goroutine 也会在程序进入阻塞方法之前使用。换句话说,stdcopy 阻塞方法在新线程中运行,而主线程与其并行运行。但是,阻塞方法现在会阻塞新线程,这并不能解决问题。
我试图防止这个问题的方法是在主线程中显式关闭这个 readcloser,然后向持有 stdcopy 阻塞方法的新线程发送一个 eof,以通过超时错误强制停止它。这应该会阻止整个程序挂起,因为阻塞方法是它挂起的原因。我通过存储我打开的每个 readcloser 的映射来做到这一点,然后以特定方法手动关闭它们,该方法旨在在我们的程序停止时运行。我不确定关闭 readcloser 接口是否会自动发送 eof(我检查了 golang 文档,但找不到任何相关信息:https://golang.org/pkg/io/#readcloser)。
我决定明确地向 readcloser 发送一个 eof,以防万一。然而,我该怎么做呢?我正在考虑利用我对通道的了解,并通过通道将 io.eof 传递到正在运行阻塞方法的 go 例程中。但是,io.readcloser 不是通道类型,所以我不能这样做。
关闭 io.readcloser 是否会自动发送 eof?如果不是,如何将 eof 发送到 io.readcloser 以便阻止方法停止运行?
如果我的解释中有任何不合理的地方并且您希望我澄清,请告诉我。由于我对 golang 比较陌生,所以如果您认为我有错误,请随时纠正我。
非常感谢您抽出宝贵的时间,如有任何想法,请告诉我!
-----编辑-----
以下是我迄今为止编写的一些代码,以便更好地理解:
//Closing all of the ReadClosers opened to prevent blocking for k := range streamer.inputReadClosers { (*k).Close() //(*k) <- io.EOF //does not work since io.ReadCloser is not of channel type }
因此,对于某些上下文,streamer 只是一个包含属性调用 inputreadclosers 的结构,它是所有打开的 readclosers 的指针映射。然后,我显式关闭 readclosers,然后目标是手动将 eof 发送到该 readcloser。
有关 readcloser 如何初始化的一些信息:
所以我有一个文件,其中有一个方法具有以下方法头 func (streamer *logstreamer) startstreamingfromdockerlogs(input io.readcloser) error
。当我检查其他文件中使用 startstreamingfromdockerlogs(...)
的实例时,我发现传递了一个 readcloser 变量,并且 readcloser 变量按以下方式初始化: readcloser, err := dockermanager.getcontainerlogs(.. ...这里三个参数.....)
。
正确答案
这实际上是一条评论,而不是一个答案,只是它太大而无法成为评论(并且需要一些格式)。
这里存在一些根本性的不匹配,使得这个问题无法解决,如上所述:
首先,文件结束符(例如由
io.eof
错误表示)不能通过任何类型的数据流发送。这是一个适用于流的条件,在该条件下无法接收更多数据(至少目前如此,该条件将来可能会消失)。其次,
io.readcloser
就是实现read
和close
方法的任何东西(具有io.reader
和io.closer
)。您不能将 eof“发送”到此。当其read
函数返回io.eof
错误作为其两个返回值之一时,就会发生 eof。如果某个类型t实现了io.readcloser
,并且您将t类型的值传递给某个函数f,并且f em> 调用其read
方法,并返回io.eof
作为其错误条件,然后此 t 的读取器已生成 eof 条件。
如 Penelope Stevens said in a comment 所示,如果我们知道恰好实现 io.readcloser
的实际具体类型 tc,那么我们也许能够找到某种方法说服 tc 的阅读器返回 io.eof
错误。这反过来又需要检查tc的源代码或文档。例如:
type Foo struct { // unexported fields TemporaryEOF bool } ... func (Foo *f) Read(p []byte) (n int, err error) { // if we're supposed to assert a temporary EOF now, do so if f->temporaryEOF { return 0, io.EOF } // rest of code here } // implement io.Closer() here too
这告诉我们,foo
对象实际上实现了 io.readcloser
,只需将其 temporaryeof
数据字段设置为 true
即可强制在一段时间内显示 eof。
这不适用于实现 io.readcloser
的其他项目,因为它们没有 temporaryeof
数据字段。这种在程序运行期间强制 eof 一段时间的特殊方法是 foo
对象所特有的。 这正是我们无法解决的问题,因为我们没有正确的信息:导致 eof 条件发生的代码是 read
函数中 tc 的代码。除非您向我们展示该代码(或者允许我们找到该代码的东西),否则我们无法告诉您如何使其产生 eof 条件。
今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习