Go 语言并发编程系列教程(十五)—— sync 包(五):临时对象池 sync.Pool

前面我们已经陆续介绍了 sync 包提供的各种同步工具,比如互斥锁、条件变量、原子操作、多协程协作等,今天我们来看另外一种工具。 在高并发场景下,我们会遇到很多问题,垃圾回收(GC)就是其中之一。Go 语言中的垃圾回收是自动执行的,这有利有弊,好处是避免了程序员手动对垃圾进行回收,简化了代码编写和维护,坏处是垃圾回收的时机无处不在,这在无形之中增加了系统运行时开销。在对系统性能要求较高的...

Go 语言并发编程系列教程(十四)—— 通过 context 包提供的函数实现多协程之间的协作

上篇教程学院君介绍了如何通过 sync.WaitGroup 类型优化通道对多协程协调的处理,但是现在有一个问题,就是我们在启动子协程之前都已经明确知道子协程的总量,如果不知道的话,该怎么实现呢? 一种解决方案是通过 sync.WaitGroup 分批启动子协程,具体实现代码如下: package main import ( "fmt" "sync" ) func ad...

Go 语言并发编程系列教程(十三)—— sync 包(四):sync.WaitGroup 和 sync.Once

在介绍通道的时候,如果启用了多个子协程,我们是这样实现主协程等待子协程执行完毕并退出的:声明一个和子协程数量一致的通道数组,然后为每个子协程分配一个通道元素,在子协程执行完毕时向对应的通道发送数据;然后在主协程中,我们依次读取这些通道接收子协程发送的数据,只有所有通道都接收到数据才会退出主协程。 代码看起来是这样的: chs := make([]chan int, 10) for i :...

基于 Laravel 开源项目 BookStack 构建知识管理与服务平台

项目简介 BookStack 是一个开源的、基于 Laravel + Vue.js 构建的知识管理和服务项目,我们可以基于它来快速构建文档、教程、wiki 管理系统,该项目开发过程中使用了以下技术栈: Laravel TinyMCE(富文本编辑器) CodeMirror(文本编辑器,适用于编辑代码) Vue.js Sortable & Vue.Draggable(排序和拖拽组件) Go...

Go 语言并发编程系列教程(十一)—— sync 包(二):条件变量 sync.Cond

sync 包还提供了一个条件变量类型 sync.Cond,它可以和互斥锁或读写锁(以下统称互斥锁)组合使用,用来协调想要访问共享资源的线程。 不过,与互斥锁不同,条件变量 sync.Cond 的主要作用并不是保证在同一时刻仅有一个线程访问某一个共享资源,而是在对应的共享资源状态发送变化时,通知其它因此而阻塞的线程。条件变量总是和互斥锁组合使用,互斥锁为共享资源的访问提供互斥支持,而条件变...

Go 语言并发编程系列教程(十)—— sync 包(一):sync.Mutex 和 sync.RWMutex

sync 包 我们前面反复强调,在 Go 语言并发编程中,倡导「使用通信共享内存,不要使用共享内存通信」,而这个通信的媒介就是我们前面花大量篇幅介绍的通道(Channel),通道是线程安全的,不需要考虑数据冲突问题,面对并发问题,我们始终应该优先考虑使用通道,它是 first class 级别的,但是纵使有主角光环加持,通道也不是万能的,它也需要配角,这也是共享内存存在的价值,其他语言中...

Go 语言并发编程系列教程(九)—— 利用多核 CPU 实现并行计算

开始之前,我们先澄清两个概念,「多核」指的是有效利用 CPU 的多核提高程序执行效率,「并行」和「并发」一字之差,但其实是两个完全不同的概念,「并发」一般是由 CPU 内核通过时间片或者中断来控制的,遇到 IO 阻塞或者时间片用完时会交出线程的使用权,从而实现在一个内核上处理多个任务,而「并行」则是多个处理器或者多核处理器同时执行多个任务,同一时间有多个任务在调度,因此,一个内核是无法实...

Go 语言并发编程系列教程(八)—— 通道类型篇(四):错误和异常处理

在前面几篇通道教程中,我们陆续介绍了与通道相关的基本语法、单向通道以及 select 语句,有关通道的基本知识就介绍到这里,今天我们来看下通道使用过程中的错误和异常处理。 在并发编程的通信过程中,最需要处理的就是超时问题:比如向通道发送数据时发现通道已满,或者从通道接收数据时发现通道为空。如果不正确处理这些情况,很可能会导致整个协程阻塞并产生死锁。此外,如果我们试图向一个已经关闭的通道发...