Go中阻塞以及非阻塞操作实现(Goroutine和main Goroutine)

 更新时间:2024年05月15日 10:28:47   作者:vSeanere  
本文主要介绍了Go中阻塞以及非阻塞操作实现(Goroutine和main Goroutine),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

main函数本身也是一个Goroutine。

在Go语言中,main函数是程序的入口点。当程序启动时,Go运行时会创建一个名为main的Goroutine,并在其中执行main函数的代码。这个main Goroutine 是程序中的主要执行线程,它负责执行main函数中的指令和操作。

与其他用户创建的Goroutine类似,main Goroutine 也是并发执行的。它可以与其他Goroutine同时执行,利用多核处理器的并行性。

main Goroutine 的生命周期与程序的生命周期相同。当main函数执行完成或显式调用os.Exit函数终止程序时,main Goroutine 会随之结束。其他正在执行的Goroutine也会被终止,程序会退出。

因此,我们可以把main函数看作是程序中的一个特殊的Goroutine,它是程序的入口和控制中心。通过在main函数内部启动其他Goroutine,我们可以实现多个任务的并发执行,充分利用Go语言的并发能力。

Go语言中,阻塞和非阻塞是用来描述对某个操作的等待行为的。

阻塞(Blocking):当执行一个操作时,如果该操作无法立即完成,程序会被阻塞,即暂停执行,直到该操作完成或满足某个条件。在阻塞状态下,程序无法继续执行其他任务,直到阻塞的操作完成。例如,当我们读取一个通道(channel)时,如果通道中没有可读取的数据,读取操作将会阻塞,直到有数据可读。

package main

import (
	"fmt"
	"time"
)

func main() {
	ch := make(chan int) // 创建一个通道

	go func() {
		time.Sleep(2 * time.Second)
		ch <- 42 // 向通道发送数据
	}()

	fmt.Println("Waiting for data...")
	data := <-ch // 从通道接收数据,如果通道中没有数据,该行会阻塞等待
	fmt.Println("Received data:", data)
}

在上述示例中,我们创建了一个通道ch,并在一个Goroutine中等待2秒后向通道发送了数据(你可以尝试修改time.Sleep函数后的数字,分别运行来看效果)。在主Goroutine中,我们尝试从通道ch中接收数据。由于通道中没有数据可用,接收操作会被阻塞,直到数据发送到通道为止。

非阻塞(Non-blocking):当执行一个操作时,如果该操作无法立即完成,程序不会被阻塞,而是立即返回,不管操作是否成功或者完成。通过使用非阻塞操作,程序可以继续执行其他任务,而不需要等待阻塞的操作完成。例如,使用非阻塞的方式读取通道时,如果通道中没有数据可读,读取操作会立即返回一个错误或默认值。

package main

import (
	"fmt"
	"time"
)

func main() {
	ch := make(chan int) // 创建一个通道

	go func() {
		time.Sleep(2 * time.Second)
		ch <- 42 // 向通道发送数据
	}()

	fmt.Println("Waiting for data...")
	select {
	case data := <-ch: // 尝试从通道接收数据
		fmt.Println("Received data:", data)
	default:
		fmt.Println("No data available")
	}
}

在上述示例中,我们使用select语句来尝试从通道ch中接收数据。如果通道中没有可用的数据,select语句会立即执行default分支,输出"No data available",而不会阻塞等待。这样,程序可以继续执行其他任务,而不需要等待数据的到达。

阻塞和非阻塞是用来描述对于某个操作的等待行为的概念。阻塞表示当一个操作无法立即完成时,程序会暂停执行,直到操作完成。非阻塞表示当一个操作无法立即完成时,程序会立即返回,继续执行其他任务。在Go语言中,通常使用通道操作来展示阻塞和非阻塞的概念。

到此这篇关于Go中阻塞以及非阻塞操作实现(Goroutine和main Goroutine)的文章就介绍到这了,更多相关Go 阻塞 非阻塞内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go中的new()和make()函数区别及底层原理详解

    Go中的new()和make()函数区别及底层原理详解

    这篇文章主要为大家介绍了Go中的new()和make()函数区别及底层原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 一文带你掌握GoLang中的指针

    一文带你掌握GoLang中的指针

    针是 Go 编程语言的重要组成部分,它们提供了一种直接引用和操作内存中数据的方法,在这篇文章中,我们将探讨一些技巧和技巧,以掌握 GoLang 中的指针并编写高效的代码,需要的可以参考一下
    2023-05-05
  • Go接口构建可扩展Go应用示例详解

    Go接口构建可扩展Go应用示例详解

    本文深入探讨了Go语言中接口的概念和实际应用场景。从基础知识如接口的定义和实现,到更复杂的实战应用如解耦与抽象、多态、错误处理、插件架构以及资源管理,文章通过丰富的代码示例和详细的解释,展示了Go接口在软件开发中的强大功能和灵活性
    2023-10-10
  • go原子级内存操作实现

    go原子级内存操作实现

    原子级内存操作是在多线程并发执行时,能够确保某个内存操作是不可中断的操作,本文主要介绍了go原子级内存操作实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • 如何使用工具自动监测SSL证书有效期并发送提醒邮件

    如何使用工具自动监测SSL证书有效期并发送提醒邮件

    本文介绍了如何开发一个工具,用于每日检测SSL证书剩余有效天数并通过邮件发送提醒,工具基于命令行,通过SMTP协议发送邮件,需配置SMTP连接信息,本文还提供了配置文件样例及代码实现,帮助用户轻松部署和使用该工具
    2024-10-10
  • Golang errors包快速上手

    Golang errors包快速上手

    errors 包是用于处理错误的标准库, errors 包提供的功能比较简单,使用起来非常方便,下面就来介绍一下,感兴趣的可以了解一下
    2025-05-05
  • Go语言单线程运行也会有的并发问题解析

    Go语言单线程运行也会有的并发问题解析

    这篇文章主要为大家介绍了Go语言单线程运行的并发问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • golang中值类型/指针类型的变量区别总结

    golang中值类型/指针类型的变量区别总结

    golang的值类型和指针类型receiver一直是大家比较混淆的地方,下面这篇文章主要给大家总结介绍了关于golang中值类型/指针类型的变量区别的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • 重学Go语言之如何使用Redis

    重学Go语言之如何使用Redis

    Redis是我们开发应用程序中很常用的NoSQL数据库,那么在Go语言中要如何连接和操作Redis呢,在这篇文章中,我们就来一起来探究一下吧
    2023-08-08
  • Go语言中JSON文件的读写操作

    Go语言中JSON文件的读写操作

    本文主要介绍了Go语言JSON文件的读写操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04

最新评论