Go使用chan或context退出协程示例详解

 更新时间:2023年08月15日 17:27:38   作者::Darwin  
这篇文章主要为大家介绍了Go使用chan或context退出协程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

问题

go两个协程使用了同一个文件句柄,其中一个协程关闭了这个文件句柄并退出了协程,如何及时通知另一个协程退出?

分析

当一个协程关闭了这个文件对象后,底层文件的文件描述符就会被释放。

这个时候,另一个协程还持有着同一个文件对象,但其实对应的文件描述符已经不存在了。

所以当第二个协程通过这个文件对象再对文件进行操作的时候,例如读写文件等,就会发生异常,比如文件描述符不存在错误等。

解决

为了避免这个问题,共享文件对象的多个协程需要通过一个通道或锁进行协调:

每个协程在使用文件对象前需要获得锁或从通道接收通知。

最后关闭文件对象的协程在关闭后,通过通道或解锁来通知其他协程对象已经无效。

其他协程收到通知后,就不再对这个已关闭的文件对象进行操作。

1. 使用 channel 通道

在主协程中,可以定义一个 channel,用来通知其它协程退出。协程在执行时可以监听这个 channel,一旦接收到退出通知,就可以进行清理工作,并退出协程。

quit := make(chan bool)
go func() {
    defer fmt.Println("Goroutine exit")
    for {
        select {
        case <-quit:
            return
        default:
            // ...
        }
    }
}()
// 主协程中发送退出通知
quit <- true

2. 使用 context 包

Go 语言标准库中提供了 context 包,可以用来控制协程的生命周期。

在主协程中可以创建一个 context 对象,并将其传递给协程,然后调用 cancel 方法,通知所有协程退出。

context.Background() 是 Go 上下文系统中一个重要的初始预定义上下文值,代表了一个没有截止时间限制的空上下文环境。

1.使用WithCancel函数创建上下文和取消函数

ctx, cancel := context.WithCancel(context.Background())
go func(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("exit")
            return
        default:
            // 执行一些耗时的操作
            time.Sleep(1 * time.Second)
            fmt.Println("running")
        }
    }
}(ctx)
time.Sleep(5 * time.Second)
// cancel()
fmt.Println("cancelled")
time.Sleep(1 * time.Second)

2.使用Deadline超时结束协程

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second))

3.使用WithTimeout限定操作时间

ctx, cancel := context.WithTimeout(context.Background(), time.Second)

以上就是Go使用chan或context退出协程示例详解的详细内容,更多关于Go chan context退出协程的资料请关注脚本之家其它相关文章!

相关文章

  • golang中interface接口的深度解析

    golang中interface接口的深度解析

    什么是interface,简单的说,interface是一组method的组合,下面这篇文章主要给大家深度解析了关于golang中的interface接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • go语言简单网络程序实例分析

    go语言简单网络程序实例分析

    这篇文章主要介绍了go语言简单网络程序实现方法,实例分析了服务器端与客户端的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Golang中Gin框架中如何定义路由详解

    Golang中Gin框架中如何定义路由详解

    Gin是一个用Go语言编写的Web框架,具有高性能和易于使用的特点,本文将结合实际案例,详细介绍Gin框架的路由用法,有需要的小伙伴可以参考下
    2024-10-10
  • 详解如何在Go中循环中使用Defer关键字示例详解

    详解如何在Go中循环中使用Defer关键字示例详解

    这篇文章主要为大家介绍了详解如何在Go中循环中使用Defer关键字示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 更高效的GoLevelDB:shardingdb实现分片和并发读写操作

    更高效的GoLevelDB:shardingdb实现分片和并发读写操作

    这篇文章主要介绍了更高效的GoLevelDB:shardingdb实现分片和并发读写操作的相关资料,需要的朋友可以参考下
    2023-09-09
  • Go时间格式化的实现

    Go时间格式化的实现

    本文主要介绍了Go时间格式化的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • golang快速实现网页截图的方法

    golang快速实现网页截图的方法

    这篇文章主要介绍了golang快速实现网页截图的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • golang开启mod后import报红的简单解决方案

    golang开启mod后import报红的简单解决方案

    这篇文章主要给大家介绍了关于golang开启mod后import报红的简单解决方案,文中通过图文将解决的办法介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • go语言制作的zip压缩程序

    go语言制作的zip压缩程序

    这篇文章主要介绍了go语言制作的zip压缩程序,其主体思路是首先创建一个读写缓冲,然后用压缩器包装该缓冲,用Walk方法来将所有目录下的文件写入zip,有需要的小伙伴参考下。
    2015-03-03
  • go语言beego框架jwt身份认证实现示例

    go语言beego框架jwt身份认证实现示例

    这篇文章主要为大家介绍了go语言beego框架jwt身份认证实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04

最新评论