GoLang之网络并发编程

介绍

并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

网络程序性能比较差、网络流量高时容易发生并发问题。并发涉及进程、线程的执行,以及CPU对进程、线程的调度等问题,如果没有控制好并发的应对处理,可能造成程序执行错误(如超卖、支付数据错误等严重问题),也会造成网站系统瘫痪等问题。因此并发问题需要对程序的优化、系统调优处理。Go语言自身性能优良、以及提供协程、消息队列等特性,可以有效应对并发问题。

参考

Go语言基础可参看:《Go语言入门及技术指南》 https://blog.csdn.net/yan_dk/article/details/110557155

《GoLang之网络基本编程》https://blog.csdn.net/yan_dk/article/details/117621468

示例

示例(协程)

需求:业务程序中存在同时调用redis、mysql、文件处理的逻辑,假设redis需要1秒,mysql需要2秒,文件处理需要3秒,按传统的网络请求处理需要6秒,如何优化?

方案:使用GoLang的协程处理。

程序01/main.go

package main

import (
	"fmt"
	"time"
)
func redis()  {
	fmt.Println("start redis")
	time.Sleep(time.Second*1)
	fmt.Println("redis execting...")
	fmt.Println("end redis")
}
func mysql()  {
	fmt.Println("start mysql")
	time.Sleep(time.Second*2)
	fmt.Println("mysql execting...")
	fmt.Println("end mysql")
}

func file()  {
	fmt.Println("start file")
	time.Sleep(time.Second*3)
	fmt.Println("file execting...")
	fmt.Println("end file")
}
func  main()  {
	fmt.Println(time.Now())
	//time.Sleep(time.Second*6)
	go redis()
	go mysql()
	go file()
	time.Sleep(time.Second*3)//主进程设置延时,不然执行过快,看不到线程的输出内容
	fmt.Println(time.Now())

}

运行结果

耗时3秒,性能提高一倍。

程序02/main.go(使用线程等待组方式)

package main

import (
	"fmt"
	"sync"
	"time"
)
//使用线程等待组
var wg sync.WaitGroup
func redis()  {
	defer wg.Done() // 结束登记
	fmt.Println("start redis")
	time.Sleep(time.Second*1)
	fmt.Println("redis execting...")
	fmt.Println("end redis")
}
func mysql()  {
	defer wg.Done() // 结束登记
	fmt.Println("start mysql")
	time.Sleep(time.Second*2)
	fmt.Println("mysql execting...")
	fmt.Println("end mysql")
}

func file()  {
	defer wg.Done() // 结束登记
	fmt.Println("start file")
	time.Sleep(time.Second*3)
	fmt.Println("file execting...")
	fmt.Println("end file")
}
func  main()  {
	fmt.Println(time.Now())
	//time.Sleep(time.Second*6)
	wg.Add(1) // 登记协程
	go redis()
	wg.Add(1) // 登记协程
	go mysql()
	wg.Add(1) // 登记协程
	go file()
	//time.Sleep(time.Second*3)
	wg.Wait() // 等待登记的协程执行完再执行后续的程序
	fmt.Println(time.Now())

}

运行 结果同上。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
本书作者带你一步一步深入这些方法。你将理解 Go语言为何选定这些并发模型,这些模型又会带来什么问题,以及你如何组合利用这些模型中的原语去解决问题。学习那些让你在独立且自信的编写与实现任何规模并发系统时所需要用到的技巧和工具。 理解Go语言如何解决并发难以编写正确这一根本问题。 学习并发与并行的关键性区别。 深入到Go语言的内存同步原语。 利用这些模式中的原语编写可维护的并发代码。 将模式组合成为一系列的实践,使你能够编写大规模的分布式系统。 学习 goroutine 背后的复杂性,以及Go语言的运行时如何将所有东西连接在一起。 作者简介 · · · · · · Katherine Cox-Buday是一名计算机科学家,目前工作于 Simple online banking。她的业余爱好包括软件工程、创作、Go 语言(igo、baduk、weiquei) 以及音乐,这些都是她长期的追求,并且有着不同层面的贡献。 目录 · · · · · · 前言 1 第1章 并发概述 9 摩尔定律,Web Scale和我们所陷入的混乱 10 为什么并发很难? 12 竞争条件 13 原子性 15 内存访问同步 17 死锁、活锁和饥饿 20 确定并发安全 28 面对复杂性的简单性 31 第2章 对你的代码建模:通信顺序进程 33 并发与并行的区别 33 什么是CSP 37 如何帮助你 40 Go语言并发哲学 43 第3章 Go语言并发组件 47 goroutine 47 sync包 58 WaitGroup 58 互斥锁和读写锁 60 cond 64 once 69 池 71 channel 76 select 语句 92 GOMAXPROCS控制 97 小结 98 第4章 Go语言并发模式 99 约束 99 for-select循环103 防止goroutine泄漏 104 or-channel 109 错误处理112 pipeline 116 构建pipeline的最佳实践 120 一些便利的生成器 126 扇入,扇出 132 or-done-channel 137 tee-channel 139 桥接channel模式 140 队列排队143 context包 151 小结 168 第5章 大规模并发 169 异常传递169 超时和取消 178 心跳 184 复制请求197 速率限制199 治愈异常的goroutine 215 小结 222 第6章 goroutine和Go语言运行时 223 工作窃取223 窃取任务还是续体 231 向开发人员展示所有这些信息 240 尾声 240 附录A 241

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云焰

你的鼓励是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值