首页 > 编程语言 >Go语言并发编程实践

Go语言并发编程实践

时间:2023-08-29 09:02:21浏览次数:40  
标签:协程 fmt 编程 并发 Go channel

Go语言是一门现代化的编程语言,以其独特而强大的并发模型而著名。Go通过轻量级的协程(goroutine)和通信机制(channel)实现了高效的并发编程。本篇博客将介绍Go语言的并发模型,讨论并发编程的基本概念和常用模式,并探索如何利用Go的并发特性来提升程序性能和开发效率。

并发编程的重要性

在计算机发展的过程中,单核处理器的性能已经达到物理极限,因此并发编程成为提高程序性能和响应能力的关键。并发编程能够充分利用多核处理器和分布式系统的资源,提高程序的吞吐量和执行效率。然而,并发编程也带来了一系列挑战,如死锁、竞态条件等问题。

Go语言的并发模型

Go语言以其独特的并发模型在编程界引起了广泛关注。Go通过goroutine和channel实现了高效的并发编程。
1.协程(goroutine):Go语言通过轻量级的协程(goroutine)实现并发。协程是由Go运行时(Goroutine Scheduler)所管理的,与线程相比,协程的切换开销极小,可以轻松创建和销毁,因此能够高效地处理大量的任务。
2.通信机制(channel):Go语言通过channel提供了协程之间的通信机制。channel是一种类型安全的、支持并发读写的数据结构。通过channel,协程之间可以传递数据和同步操作,从而实现了数据的安全共享和同步执行。

并发编程的基本概念和常用模式

1.并发与并行:并发是指任务的交替执行,而并行是指任务的同时执行。并发编程旨在将任务切分为多个子任务,并通过调度器在不同的协程之间进行切换以实现并发执行。
2.同步与异步:同步是指协程之间的操作按照顺序执行,异步是指协程之间的操作可以无需等待立即执行。Go通过channel实现了同步和异步操作的灵活组合,提供了统一的编程接口。
3.互斥锁(Mutex):互斥锁是一种常见的同步机制,用于保护共享资源的访问。在Go中,可以使用互斥锁来控制对共享资源的并发访问,确保数据的一致性和线程安全。
4.条件变量(Condition):条件变量用于协调协程之间的执行顺序。当某个条件不满足时,协程可以进入等待状态,直到其他协程满足条件后通知它继续执行。
5.并发安全的数据结构:Go语言提供了一系列并发安全的数据结构,如sync包中的WaitGroup、Once、RWMutex等,可以方便地实现并发编程中常见的模式和用例。

Go并发编程示例

下面是一个简单的并行计算的示例代码:

package main  
  
import (  
    "fmt"  
    "runtime"  
    "sync"  
)  
  
func calculateSquare(num int, wg *sync.WaitGroup) {  
    square := num * num  
    fmt.Println("Square of", num, "is", square)  
    wg.Done()  
}  
  
func main() {  
    nums := []int{1, 2, 3, 4, 5}  
  
    var wg sync.WaitGroup  
    wg.Add(len(nums))  
  
    for _, num := range nums {  
        go calculateSquare(num, &wg)  
    }  
  
    wg.Wait()  
  
    fmt.Println("All calculations are done.")  
}

在上面的代码中,我们定义了一个calculateSquare函数,用于计算一个数的平方,并打印结果。然后,我们使用sync.WaitGroup来等待所有计算完成。

异步IO:在IO密集型任务中,使用协程和非阻塞IO操作可以实现高效的异步处理,从而充分利用CPU资源,提高程序的吞吐量。
可以通过使用goroutine和非阻塞IO来实现异步IO操作。以下是一个简单的示例:

package main  
  
import (  
    "fmt"  
    "io/ioutil"  
    "net/http"  
)  
  
func fetchURL(url string, ch chan<- int) {  
    resp, err := http.Get(url)  
    if err != nil {  
        fmt.Println("Error:", err)  
        ch <- 1  
        return  
    }  
    defer resp.Body.Close()  
  
    _, err = ioutil.ReadAll(resp.Body)  
    if err != nil {  
        fmt.Println("Error:", err)  
        ch <- 1  
        return  
    }  
  
    fmt.Println("Fetched", url)  
    ch <- 0  
}  
  
func main() {  
    urls := []string{"https://example.com", "https://google.com", "https://facebook.com"}  
  
    ch := make(chan int, len(urls))  
  
    for _, url := range urls {  
        go fetchURL(url, ch)  
    }  
  
    for range urls {  
        status := <-ch  
        if status != 0 {  
            fmt.Println("Some URLs failed to fetch.")  
            return  
        }  
    }  
  
    fmt.Println("All URLs fetched successfully.")  
}

在上面的代码中,我们定义了一个fetchURL函数,用于异步获取给定URL的内容。我们使用http.Get进行非阻塞的IO操作。通过使用一个带缓冲区的channel,我们可以通过接收channel的值来进行状态检查,以确保所有的URL都被成功获取。

Go并发编程的最佳实践

在进行Go并发编程时,还有一些最佳实践可以帮助开发者避免常见的陷阱和问题:

1.避免共享数据:尽量避免多个协程之间共享数据,而是通过消息传递的方式进行数据交换。
2.避免竞争条件:合理使用互斥锁和其他同步机制,避免多个协程竞争共享资源而导致的问题。
3.避免阻塞操作:使用非阻塞式的IO操作,以充分利用协程的并发性能。
4.处理错误:在协程中及时处理错误,确保代码的鲁棒性和稳定性。

标签:协程,fmt,编程,并发,Go,channel
From: https://www.cnblogs.com/johnsonstar/p/17663807.html

相关文章

  • windows 下 MongoDB安装与配置
    ​ 一:安装1、官网下载官网下载地址:https://www.mongodb.com/try/download/community 下载社区​编辑​ 下载需要的版本、平台、安装方式即可,2、安装    直接傻瓜式安装即可,直到安装完成    1.选择安装方式:选择默认安装或者自定义安装,我这儿是选的自定......
  • 图像处理与分析编程实践
      日期2022-10-29  打开图像,显示图像,灰度化,二值化,存储图像,缩放图像,观察其分辨率,降低灰度分辨率两种模式,观察图像变化;原图,像素尺寸:700x350  如见显示图像,效果图如下:  灰度化后得到的图片如下:  二值化后得到图片如下:  图片放大10倍后,得到的图片局部如下:  图片缩小1......
  • Data structure and algorithm-Two
    B树                扩容           找出不含重复字符的最长字串的长度 字母异位词分组   优化用一个长度26的整数数组来标识 ArrayKey的构造方法   判断是否存在重复元素 ......
  • Go 格式化动词
    Printf()函数可以使用多种格式化动词对输出进行格式化。下面是可以与所有数据类型一起使用的一些通用格式化动词:通用格式化动词:以下动词适用于所有数据类型:动词描述%v以默认格式打印值%#v以Go语法格式打印值%T打印值的类型%%打印百分号示例:packa......
  • kali linux上webgoat搭建报错解决
    从 https://github.com/WebGoat/WebGoat/releases 下载最新的WebGoat版本(可以直接下载源码或者git下载)gitclonehttps://github.com/WebGoat/WebGoat/WebGoat.git网络问题连接失败可以通过直接下载源码把下载链接放到加速网站(https://ghproxy.com/)https://git......
  • 编程语言的一点区别
    编程语言的一点区别Python解释型语言,必须允许在解释器之上pyinstaller--可以吧这个py打包成exe本质就是把解释器也打包进去了,所以exe显得大go编译型,跨平台。开发时需要开发环境,运行时不需要。对运维特别友好java是编译型--字节码文件jdk:java开发工具包,包含j......
  • golang官方包管理vendor模式无法引用非go文件
    主页微信公众号:密码应用技术实战博客园首页:https://www.cnblogs.com/informatics/背景&问题golang作为高级计算机语言之一,在云原生以及web网站建设中发挥了重要作用,但在实际应用中我们可能会碰到以下场景,在该场景下:部署机无法访问外网,无法直接从互联网下载依赖包golang依......
  • 萌萌哒桌面宠物“手鼓猫 Bongo Cat Mver”
    BongoCatMver是一款可爱Q萌、实用的鼠标键盘替身演示工具。BongoCatMver适用于各种主播用户,用户只需要将这个小猫敲键盘的动画放置在电脑窗口上的任何位置,即可将用户所做出的各种键盘鼠标操作实时显示在卡通形象上。BongoCatMver还支持很多动作表情的自定义。BongoCatMver软件功能......
  • Go文件操作
    写文件packagemainimport( "fmt" "os")funcmain(){ f1,err:=os.Create("/Users/db/go_project/BeegoDemo/test.txt")//新建文件 //f2,err2:=os.OpenFile("/Users/db/go_project/BeegoDemo",os.O_CREATE,0666)//新建文件......
  • Golang数据库标准库
    驱动连接数据库是典型的CS架构,服务器端被动等待客户端建立TCP连接,并在此连接上进行特定的应用层协议。但一般用户并不需要了解这些细节,这些都被打包到驱动库中,只需要简单的调用打开就可以执行协议连接到指定的数据库。数据库的种类和产品很多,协议也很多,Go官方很难提供针对不同数据......