0

0

如何永久阻塞 Go 程序/Goroutine?

心靈之曲

心靈之曲

发布时间:2025-10-29 12:42:01

|

778人浏览过

|

来源于php中文网

原创

如何永久阻塞 go 程序/goroutine?

本文介绍了在 Go 语言中永久阻塞主 Goroutine 的几种方法,以便让后台 Goroutine 继续运行。重点讲解了使用 select {} 语句实现永久阻塞,并简要提及了 sync.WaitGroup 的使用场景。针对不需要关注后台 Goroutine 结果的情况,select {} 提供了一种简洁高效的解决方案。

在 Go 语言中,有时我们需要启动一些后台 Goroutine 来执行任务,然后阻塞主 Goroutine,让这些后台 Goroutine 继续运行。本文将介绍几种实现永久阻塞的方法。

使用 select {} 永久阻塞

最简洁且推荐的方式是使用 select {} 语句。根据 Go 语言规范,当 select 语句没有任何 case 并且所有 channel 都为 nil 时,该语句将永久阻塞。

package main

import (
    "fmt"
    "time"
)

func backgroundTask() {
    for {
        fmt.Println("Background task running...")
        time.Sleep(1 * time.Second)
    }
}

func main() {
    go backgroundTask()

    fmt.Println("Main goroutine starting...")

    select {} // 永久阻塞主 Goroutine
}

在这个例子中,backgroundTask 函数会在后台持续运行,打印 "Background task running..."。main 函数启动了这个 Goroutine 后,执行 select {} 语句,从而永久阻塞主 Goroutine,使得后台任务得以持续执行。

原理:

select {} 实际上是一个空的 select 语句。由于没有任何 case 分支可以执行,并且没有默认分支,select 语句会无限期地等待,从而阻塞当前的 Goroutine。

Groq
Groq

GroqChat是一个全新的AI聊天机器人平台,支持多种大模型语言,可以免费在线使用。

下载

优点:

  • 简洁: 代码非常简洁易懂。
  • 高效: select {} 会将控制权让给其他 Goroutine,避免 CPU 占用。

使用 sync.WaitGroup (不推荐用于永久阻塞)

sync.WaitGroup 通常用于等待一组 Goroutine 完成。虽然它可以用来阻塞主 Goroutine,但这并不是它的主要用途,并且如果使用不当,可能会导致程序无法正常退出。

package main

import (
    "fmt"
    "sync"
    "time"
)

func backgroundTask(wg *sync.WaitGroup) {
    defer wg.Done() // 确保 Goroutine 退出时调用 Done()
    for {
        fmt.Println("Background task running...")
        time.Sleep(1 * time.Second)
    }
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1) // 增加计数器

    go backgroundTask(&wg)

    fmt.Println("Main goroutine starting...")

    wg.Wait() // 等待 WaitGroup 计数器变为 0
    fmt.Println("Main goroutine exiting...") //永远不会执行到这里
}

在这个例子中,wg.Wait() 会阻塞主 Goroutine,直到 wg.Done() 被调用足够多的次数,使得计数器变为 0。 由于后台任务是无限循环的,wg.Done() 永远不会被调用,所以主 Goroutine 将永久阻塞。

注意事项:

  • sync.WaitGroup 更适合用于等待一组 Goroutine 完成特定任务后退出。
  • 如果使用 sync.WaitGroup 进行永久阻塞,需要确保在程序退出时,能够正确地释放阻塞,否则可能导致资源泄漏或其他问题。

其他方法 (不推荐)

  • 死循环 + time.Sleep(): 虽然可以实现阻塞,但会占用 CPU 资源,不推荐使用。
  • 接收一个永远不会发送数据的 channel: var ch chan int;

总结

对于永久阻塞主 Goroutine 并且不需要关注后台 Goroutine 结果的情况,select {} 是最简洁、高效且推荐的方式。它能够有效地阻塞主 Goroutine,并将控制权让给其他 Goroutine,避免 CPU 占用。sync.WaitGroup 更适合用于等待一组 Goroutine 完成特定任务后退出。避免使用死循环 + time.Sleep() 或接收一个永远不会发送数据的 channel 这种方式。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

522

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

190

2025.08.29

Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

241

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

320

2025.11.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

43

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

35

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号