关闭从 TCP 连接读取的 goroutine,而不关闭连接

2024-01-22

我喜欢 Go 在内部处理 I/O 多路复用的方式epoll还有另一种机制并自行调度绿色线程(此处为 go-routine),从而可以自由地编写同步代码。

我知道 TCP 套接字是non-blocking and read会给EAGAIN当没有可用数据时。鉴于,conn.Read(buffer)将检测到这一点并且阻止 go 例程在套接字缓冲区中没有可用数据的情况下执行连接读取。有没有办法在不关闭底层连接的情况下停止这样的例程。我正在使用连接池,因此关闭 TCP 连接对我来说没有意义,并且希望将该连接返回到池中。

下面是模拟这种场景的代码:

func main() {
    conn, _ := net.Dial("tcp", "127.0.0.1:9090")
    // Spawning a go routine
    go func(conn net.Conn) {
        var message bytes.Buffer
        for {
            k := make([]byte, 255) // buffer
            m, err := conn.Read(k) // blocks here 
            if err != nil {
                if err != io.EOF {
                    fmt.Println("Read error : ", err)
                } else {
                    fmt.Println("End of the file")
                }
                break // terminate loop if error
            }
            // converting bytes to string for printing
            if m > 0 {
                for _, b := range k {
                    message.WriteByte(b)
                }
                fmt.Println(message.String())
            }

        }
    }(conn)

    // prevent main from exiting
    select {}
}

如果不可能,我可以采取哪些其他方法:

1) Call syscall.Read并手动处理这个问题。在这种情况下,我需要一种方法来检查套接字是否可用readable打电话之前syscall.Read否则我最终会浪费不必要的 CPU 周期。对于我的场景,我想我可以跳过基于事件的轮询并继续调用syscall.Read因为我的用例中总是有数据。

2)任何建议:)


func receive(conn net.TCPConn, kill <-chan struct{}) error {
    // Spawn a goroutine to read from the connection.
    data := make(chan []byte)
    readErr := make(chan error)
    go func() {
        for {
            b := make([]byte, 255)
            _, err := conn.Read(b)
            if err != nil {
                readErr <- err
                break
            }
            data <- b
        }
    }()


    for {
        select {
        case b := <-data:
            // Do something with `b`.
        case err := <-readErr:
            // Handle the error.
            return err
        case <-kill:
            // Received kill signal, returning without closing the connection.
            return nil
        }
    }
}

发送一个空结构到kill从另一个 goroutine 停止从连接接收。这是一个在一秒钟后停止接收的程序:

kill := make(chan struct{})
go func() {
    if err := receive(conn, kill); err != nil {
        log.Fatal(err)
    }
}()
time.Sleep(time.Second)
kill <- struct{}{}

这可能不完全是您正在寻找的,因为读取 goroutine 仍然会被阻塞Read即使您发送至kill。然而,处理传入读取的 goroutine 将终止。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关闭从 TCP 连接读取的 goroutine,而不关闭连接 的相关文章

  • Golang 正则表达式命名组和子匹配

    我正在尝试匹配正则表达式并获取匹配的捕获组名称 当正则表达式仅与字符串匹配一次时 这是有效的 但如果它与字符串匹配多次 SubexpNames不返回重复的名称 这是一个例子 package main import fmt regexp fu
  • 使用 HTTPS GRC 从 AWS Codecommit 获取私有存储库

    我正在尝试导入位于 AWS codecommit 中的模块 为了克隆存储库 我使用 HTTPS GRC Git 远程代码提交 方法 该方法使用 Google Suite 凭证来访问 AWS 控制台 我用来克隆存储库的命令是 git clon
  • 同步 I/O 是否会使线程繁忙?

    假设我正在同步 I O 套接字上执行 I O 该套接字已准备好read or write手术 这意味着调用线程不会在操作上被阻塞 无论非阻塞 SOCK NONBLOCK 套接字的阻塞性质 但以下事情我不清楚 实际转移何时发生 当套接字标记为
  • Golang GAE - 小胡子结构中的 intID

    这是一个Example https www dropbox com sh ur2ws1jnik6euef PjVJSwDTUc Blog Golang zip该应用程序的 关键代码在 golang code handler handler
  • 解组转义 XML

    在 Go 中 我将如何解码此 XML 响应 我尝试过建立一个自定义UnMarshal方法在我的Answerstruct 但我运气不太好
  • 如何强制关闭 TcpListener

    我有一个通过 tcpListener 进行通信的服务 问题是当用户重新启动服务时 抛出 地址已在使用 异常 并且服务在几分钟左右无法启动 有没有办法告诉系统终止旧连接 以便我可以打开一个新连接 我不能只使用随机端口 因为服务无法通知客户端端
  • 如何在 Laravel 中 session_write_close() ?

    Running session write close before sleep 在 Laravel 中似乎不起作用 因为会话仍然被其他请求阻止 直到当前连接完成 我试图sleep 在 Laravel 中 不会阻止其他请求 发现 sessi
  • 如何将 SQLite 数据库捆绑到 Go 二进制文件中?

    我尝试使用 go bindata 和 packr 但这些包没有显示如何将 SQLite 数据库文件打包到二进制文件中 我不需要以任何方式更新数据库 我只想在启动时从中读取数据 如何将 SQLite 数据库文件嵌入到 Go 二进制文件中 SQ
  • 使用 paramiko 运行 Sudo 命令

    我正在尝试执行sudo使用 python paramiko 在远程计算机上运行命令 我尝试了这段代码 import paramiko ssh paramiko SSHClient ssh set missing host key polic
  • perl6 IO::Socket::INET 无法从套接字接收数据:连接被对等方重置

    示例服务器 usr bin env perl6 my listen IO Socket INET new listen localhost
  • GOMAXPROCS 默认值是多少?

    不设置同名环境变量时是否保证GOMAXPROCS设置为1 此代码显示的值 package main import runtime fmt func getGOMAXPROCS int return runtime GOMAXPROCS 0
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 我在socket上设置了超时,发现这个值不能大于21

    我在socket上设置了超时 该值小于21秒才有效 21秒后发现超时还是21秒 public static void main String args SimpleDateFormat sdf new SimpleDateFormat yy
  • UI 线程中异步组件的触发事件

    我正在 Net 2 0 中构建一个非可视组件 该组件使用异步套接字 BeginReceive EndReceive 等 异步回调是在运行时创建的工作线程的上下文中调用的 组件用户不必担心多线程 这是主要目标 我想要的 组件用户可以在任何线程
  • 如何关闭 gorm 1.20.0 中的数据库实例

    由于我没有在 Close 函数中找到 gorm 实例 任何帮助将不胜感激 dbURI fmt Sprintf user s password s dbname s port s sslmode s TimeZone s username p
  • 在 Go 中,如何将结构体转换为字节数组?

    我有一个我定义的结构实例 我想将其转换为字节数组 我尝试了 byte my struct 但这不起作用 另外 我还被指出二进制包 http golang org pkg encoding binary 但我不确定我应该使用哪个函数以及应该如
  • RSA OAEP、Golang 加密、Java 解密 -BadPaddingException:解密错误

    我正在尝试解密使用 RSA OAEP 在 Golang 中加密的字符串 但出现 BadPaddingException 解密错误 很难弄清楚我错过了什么 这是Golang加密方法 func encryptString rootPEM io
  • 如何修复“缺少表的 FROM 子句条目”错误

    我正在尝试根据游戏 ID 获取平台名称 我有如下三个表 我正在尝试加入它们以获得所需的结果 Games Id 1 2 3 4 Game Platforms Id game id platform id 1 1 1 2 1 2 3 3 3
  • 在 Go to 函数中通过引用和值传递

    我对 Go 中通过引用和值传递有点困惑 我已经看到过对类型前面的 的解释 在类型名称前面 表示声明的变量将存储该类型的另一个变量的地址 而不是该类型的值 类型 这对我来说毫无意义 在Java中 如果我将数据库实例传递给函数 我会这样做 da
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a

随机推荐

  • 连接 nvarchar(max) 值似乎不起作用(+= 用作=)

    使用 SQL Server 2012 我发现尝试基于表中的 nvarchar max 列构建字符串似乎无法正常工作 它似乎是覆盖 而不是追加 任意示例 DECLARE sql nvarchar max SELECT sql N SELECT
  • Powershell 全局模式匹配

    我正在看C ProgramFiles对于一个名为log4j core x y z jar 我正在尝试匹配最后一位数字z 可以是一位数也可以是两位数 0 99 我似乎无法获得正确的全局模式来完成此任务 Code PS C Users Admi
  • Greasemonkey - 替换 javascript src 以加载自定义 JS 而不是页面之一

    js 文件中有带有变量的特定网页 我想重写Greasemonkey加载的URL 但仍然没有得到任何结果 我使用的代码是 window addEventListener load function allTextareas document
  • 如何将pystache与金字塔集成?

    我想使用 pystache 在我的金字塔应用程序中提供的基于类的视图 但我不完全确定如何正确集成两者 我读了this https stackoverflow com questions 8169606 how to change the t
  • PHP 页面之间传递变量

    我想在一个页面中获取用户输入 将其存储在 php 变量中 然后在另一个 php 页面中使用它 我尝试过使用 会话 但它似乎不起作用 还有其他安全的选择吗 该信息可能是用户名和密码 尝试更改您的会话代码 因为这是执行此操作的最佳方法 例如 索
  • 使用 CSS 样式的按钮元素在 IE6 中不显示背景图像

    我有一个针对 IE 6 的旧版 Web 应用程序 正在重新设计 这些按钮的默认浏览器按钮看起来已替换为蓝色按钮图像 我的以下 HTML 和 CSS 在 IE 8 上工作正常 但在 IE 6 上不行 HTML
  • C++ 标准中的重载与默认参数

    我正在阅读另一个问题 这引起了我的思考 标准通常会指定在其描述中具有默认参数的函数 标准是否允许将它们写为重载 例如 标准规定std basic string copy有以下声明 size type copy Ch p size type
  • git pickaxe 找不到修改的行

    今天早些时候 我正在搜索更改函数名称的提交getReportHtml to getReport 我用镐找不到它 所以我通过手动搜索找到了它 现在我知道哪个提交发生了更改 我可以在 git diff 输出中看到更改 function getR
  • Aurelia:子路由器路由显示在 app.html 元素中的“主”导航栏和子视图中?

    我们想要一个侧边栏菜单和一个 主 区域 根据您的导航方式 侧边栏的菜单项将发生变化 并且新视图将加载到 主 区域 我创建了 app html
  • UIPageViewController 转换“对开始/结束外观转换的不平衡调用”

    当我浏览时UIPageViewController比我得到的过渡动画更快 Unbalanced calls to begin end appearance transitions for
  • 如何使用对象实例作为模板参数?

    我正在学习C 我有一个 Classroom 类 它应该根据正在使用的配置对象以一种或另一种方式表现 创建 Classroom 对象时 我可以在构造函数中传递该 Configuration 对象 如下所示 class Classroom pr
  • 如何通过参数化存储过程填充列表框?

    我有一个Winforms应用程序和一个employeeListBox departmentComboBox和一些文本框来显示员工信息 例如fNameTextbox lNameTextBox 我想通过departmentCombobox 选定
  • 需要资产管道中的树

    我的资产管道中有一个名为 typefaces 的文件夹 它无需任何添加即可工作application rb 在目录中 我有不同的字体类型 例如文件夹中的 eof ttf 等 如下所示 Assets Typefaces Eof files T
  • 是否可以更改 HIVE 中的分区元数据?

    这是我之前提出的问题的延伸 如何比较具有不同数据类型组的两列 https stackoverflow com questions 58240566 how to compare two columns with different data
  • 如何在路由(react-router-dom)react js中将状态从父组件传递到子组件

    我是 React js 的新手 并使用以下命令创建了一个小型反应应用程序react router dom 其中我有两个组成部分 仪表板 dashboard js 信息 information js 和一个主要组件应用程序 App js 其中
  • ConstraintLayout 1.1.0(测试版)中链中的边距如何工作

    自从切换到 ConstraintLayout 版本 1 1 0 beta4 以来 我的几个布局都崩溃了 在进行任何更改之前 我想更好地了解利润率如何运作ConstraintLayout链 下面我比较一下布局ConstraintLayout版
  • 生成达到一定字长的每个字符组合

    几周后我将为我的计算机和信息安全课程做一个安全演示 在这个演示中我将展示不同攻击 字典 彩虹和暴力 的优缺点 我可以很好地进行字典和彩虹攻击 但我需要即时生成暴力攻击 我需要找到一种算法 可以让我循环遍历字母 符号和数字的每个组合 直到达到
  • Spring Boot 自动配置顺序

    我想创建一个 Spring Boot 自动配置类 有条件地 创建单个 beanA 然而 挑战在于 这个 bean 必须在另一个 bean 之前创建B在 Spring Boot 的默认自动配置类之一中创建 豆子B不依赖于A 我的第一次尝试是使
  • 生成一定范围内的随机数

    我以前做过这个 但现在我又在挣扎了 我想我不理解这个问题背后的数学原理 我想在两边的一个小范围内设置一个随机数1 例子是 98 1 02 94 1 1等等 我发现的所有示例都描述了在之间获取随机数0 and 100 但是我怎样才能用它来达到
  • 关闭从 TCP 连接读取的 goroutine,而不关闭连接

    我喜欢 Go 在内部处理 I O 多路复用的方式epoll还有另一种机制并自行调度绿色线程 此处为 go routine 从而可以自由地编写同步代码 我知道 TCP 套接字是non blocking and read会给EAGAIN当没有可