首页 > 其他分享 >Go可以做到同等并发能力么?具体代码如何写?

Go可以做到同等并发能力么?具体代码如何写?

时间:2023-11-03 10:44:06浏览次数:40  
标签:wg fmt Goroutine results 同等 并发 Go

 

原创 磊丰 Go语言圈 2023-09-05 08:30 发表于广东 收录于合集#学Go语言哪些事儿231个 MySQL大牛 带你全面剖析与系统梳理数据库(mysql等)知识分享,总结数据库技巧和方法,提升你的技术技能。 45篇原创内容 公众号

JetBrains全家桶正式版激活码&账号开通授权,支持版本升级

https://web.52shizhan.cn/activity/127b50

学习与交流:Go语言技术微信群

商务合作加微信:LetsFeng

 

现在就开始你的Go语言学习之旅吧!人生苦短,let’s Go.


图片

图片

Go 是一门天生支持高并发的编程语言,它通过 Goroutine 和 Channel 等特性使并发编程变得简单且高效。

以下是一个简单的示例代码,展示了 Go 如何实现高并发能力:

package main

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

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Printf("Worker %d started\n", id)
    time.Sleep(time.Second) // 模拟工作
    fmt.Printf("Worker %d finished\n", id)
}

func main() {
    const numWorkers = 5
    var wg sync.WaitGroup

    for i := 1; i <= numWorkers; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

    wg.Wait()

    fmt.Println("All workers finished")
}

在上述示例中,我们创建了 5 个 Goroutine 来模拟并发的工作。每个 Goroutine 执行 worker 函数来模拟工作,并在完成后通知 WaitGroup。主程序等待所有的 Goroutine 完成后才会继续执行。

这个例子展示了 Go 是如何通过 Goroutine 来实现并发的。Goroutine 是 Go 语言并发模型的基础,它们非常轻量级,可以在单个操作系统线程中同时运行成千上万个 Goroutine,从而实现高并发的能力。

需要注意的是,Go 的并发模型与传统的基于线程的并发模型有所不同。Goroutine 是由 Go 运行时系统进行调度的,不需要开发人员显式地管理线程。此外,为了实现 Goroutine 之间的安全通信和同步,Go 引入了 Channel,它可以用于在 Goroutine 之间传递数据和控制信号。

在实际应用中,您可以使用 Goroutine 和 Channel 来实现更复杂的并发模式,如并发任务执行、并发数据处理等。

 

并发任务执行:

假设您有一些任务需要并发地执行,您可以使用 Goroutine 来同时执行这些任务,然后使用 Channel 来汇总结果。下面是一个示例,展示如何使用 Goroutine 和 Channel 并发执行任务并收集结果:

package main

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

func worker(id int, jobs <-chan int, results chan<- int) {
    for job := range jobs {
        fmt.Printf("Worker %d started job %d\n", id, job)
        time.Sleep(time.Second) // 模拟任务执行
        results <- job * 2      // 将结果发送到通道
        fmt.Printf("Worker %d finished job %d\n", id, job)
    }
}

func main() {
    const numJobs = 10
    const numWorkers = 3

    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    // 创建并启动多个工作 Goroutine
    var wg sync.WaitGroup
    for i := 1; i <= numWorkers; i++ {
        wg.Add(1)
        go func(workerID int) {
            defer wg.Done()
            worker(workerID, jobs, results)
        }(i)
    }

    // 提供任务给工作 Goroutine
    for i := 1; i <= numJobs; i++ {
        jobs <- i
    }
    close(jobs)

    // 等待所有工作完成
    wg.Wait()
    close(results)

    // 收集任务结果
    for result := range results {
        fmt.Println("Result:", result)
    }
}

在此示例中,我们创建了一些工作任务并将它们放入 jobs 通道中,然后启动了多个工作 Goroutine 来从 jobs 通道中获取任务并执行。每个工作 Goroutine 将结果发送到 results 通道中,然后主程序从 results 通道中收集结果。

并发数据处理:

假设您有一些数据需要并发地处理,您可以将数据分割成块,并使用 Goroutine 来并发处理每个块数据。下面是一个示例,展示如何使用 Goroutine 和 Channel 并发处理数据:

package main

import (
    "fmt"
    "sync"
)

func processData(data []int, results chan<- int) {
    result := 0
    for _, num := range data {
        result += num
    }
    results <- result
}

func main() {
    data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    const numWorkers = 3

    chunkSize := len(data) / numWorkers

    results := make(chan int, numWorkers)

    var wg sync.WaitGroup
    for i := 0; i < numWorkers; i++ {
        wg.Add(1)
        start := i * chunkSize
        end := (i + 1) * chunkSize
        go func() {
            defer wg.Done()
            processData(data[start:end], results)
        }()
    }

    wg.Wait()
    close(results)

    totalResult := 0
    for result := range results {
        totalResult += result
    }

    fmt.Println("Total result:", totalResult)
}

在此示例中,我们将数据分割成多个块,每个块数据由一个工作 Goroutine 并发处理,然后将处理结果发送到 results 通道中。主程序等待所有工作完成,然后从 results 通道中收集处理结果并计算总和。

这只是一些示例,您可以根据具体的应用场景和需求,灵活地使用 Goroutine 和 Channel 来实现各种并发模式。

 

文章首发:

 

 

 

 

 

 

更多相关Go语言的技术文章或视频教程,请关注本公众号获取并查看,感谢你的支持与信任!

收录于合集 #学Go语言哪些事儿  231个 上一篇请解释一下 Go 中的反射(Reflection)是什么,以及它的应用场景下一篇go语言如何使用rabbitmq,正常消息,延时消息   阅读 1435 Go语言圈   ​       写下你的留言           复制搜一搜分享收藏划线    

人划线

标签:wg,fmt,Goroutine,results,同等,并发,Go
From: https://www.cnblogs.com/cheyunhua/p/17807086.html

相关文章

  • logstash同步mongodb到es
    环境:OS:Centos7说明:logstash本身不自带logstash-input-mongodb插件,需要自行安装。1.安装编译工具yuminstallgityuminstallgem 2.源码编译[root@localhost]#gitclonehttps://github.com/phutchins/logstash-input-mongodb.git[root@localhost]#cdlogstash-input......
  • 09Go语言基础之函数
    函数是组织好的、可重复使用的、用于执行指定任务的代码块。本文介绍了Go语言中函数的相关内容。函数Go语言中支持函数、匿名函数和闭包,并且函数在Go语言中属于“一等公民”。函数定义Go语言中定义函数使用func关键字,具体格式如下:func函数名(参数)(返回值){函数体}......
  • 08Go语言基础之map
    Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。mapmap是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。map定义Go语言中map的定义语法如下:map[KeyType]ValueType其中,KeyType:表示键的类型。ValueType:表示键对应的值的类......
  • 12Go语言基础之结构体
    Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。类型别名和自定义类型自定义类型在Go语言中有一些基本的数据类型,如string、整型、浮点型、布尔等数据类型,Go语言中可以使用type关键......
  • 16Go语言基础之接口
    接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。接口本章学习目标了解为什么需要接口以及接口的特点掌握接口的声明和使用掌握接口值的概念掌握空接口的特点及其使用场景在Go语言中接口(interface)是一种类型,一种抽象的类型。相较于......
  • Go标准库Context
    在Gohttp包的Server中,每一个请求在都有一个对应的goroutine去处理。请求处理函数通常会启动额外的goroutine用来访问后端服务,比如数据库和RPC服务。用来处理一个请求的goroutine通常需要访问一些与请求特定的数据,比如终端用户的身份认证信息、验证相关的token、请求的截止......
  • Go语言基础之error接口
    Go语言中的错误处理与其他语言不太一样,它把错误当成一种值来处理,更强调判断错误、处理错误,而不是一股脑的catch捕获异常。Error接口和错误处理Error接口Go语言中把错误当成一种特殊的值来处理,不支持其他语言中使用try/catch捕获异常的方式。Error接口Go语言中使用一个......
  • Golang中Defer知识点
    1:defer的执行顺序多个defer出现的时候,它是一个“栈”的关系,也就是先进后出。一个函数中,写在前面的defer会比写在后面的defer调用的晚packagemainimport"fmt"funcmain(){deferfunc1()deferfunc2()deferfunc3()}funcfunc1(){fmt.Println("A")......
  • Go语言标准库log介绍
    无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯。logGo语言内置的log包实现了简单的日志服务。本文介绍了标准库log的基本使用。使用Loggerlog包定义了Logger类型,该类型提供了一些格式化输出的方......
  • Go语言标准库flag基本使用
    Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。os.Args如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数。packagemainimport( "fmt" "os")//os.Argsdemofuncmain(){ //os.Args是一个[]st......