美文网首页IT@程序员猿媛Go
Go语言之通道(二)

Go语言之通道(二)

作者: 有财君 | 来源:发表于2019-05-14 23:00 被阅读3次

1. 前情回顾

Go语言提供了goroutine来简单的实现并发,对于我这种不太喜欢动脑子的人来说这是一个非常完美的方式。而且其原理易于理解,只要稍有一点计算机的基础知识就可以轻松地理解其调度机制。

并发编程很重要的一点就是线程间的通信,这一点在Go语言中也可以通过通道这个东西轻松地完成。

下面是我之前写的笔记的链接:

Go语言之通道(一)

我也就不再过多的表述通道的问题了。

2. 今天要讲的事情

我是一个DBA,当我在学习到通道的时候,我内心总是觉得这个东西很像MySQL的传统复制。

  • Master将事务写在binlog中,通知slave来取;
  • Slave接到通知,将binlog转录会本地的relaylog中;
  • Slave上有一个SQL线程负责将中继日志重放。

因此我只需要启动一个goroutine一直写binlog到通道里,另外一个goroutine一直接收这个通道传来的binlog就可以了。

那么下面就可以着手编码了:

package main

import (
    "fmt"
    "time"
)

type binlog struct {
    id int
    event string
}

var i = 1

func main() {
    transaction := make(chan binlog)
    ack := make(chan string)
    go master(transaction)
    go slave(transaction, ack)
    for {
        <- ack
    }
}

func master(transaction chan binlog) {
    for {
        //发送binlog
        transaction <- binlog{id:i, event: "commit"}
        //为了好打印观察结果,每次给通道一个值就休息1s
        time.Sleep(1 * time.Second)
        i++
    }
}

func slave(transaction chan binlog, ack chan string) {
    for {
        relaylog := <-transaction
        fmt.Printf("get binlog: %d, event is %s\n", relaylog.id, relaylog.event)
        ack <- "ok"
    }
}

这样就模拟了复制的过程:

复制模拟

然而要注意的是,我这里用的是无缓冲通道。这种通道的问题是,发送会被阻塞,直到另一个goroutine通道执行接收操作并完成。

这其实就是一个同步的过程,MySQL的复制,从来都是异步的。因此需要选择的并不是无缓冲通道来模拟,而要选择缓存通道,则比较地道。

其实代码改动起来比较简单,只需要将main函数的这里替换一下就可以:

transaction := make(chan binlog, 100)

缓冲通道的一个好处是通道关闭了以后,还是可以继续的取到通道中的值,有了这个保证,如果Master在发送完成后将通道关闭了,其实Slave还是可以接收到binlog的。这个我在之前的笔记中也是介绍过的。

3. 小结

我学Go语言,其实完全是为了开发一些帮助我完成日常DBA工作的小工具,最开始我用的是Python,这门语言上手极快,但是用完语法基本全忘,下次再开发工具的时候继续百度或者翻书。

而且我们的内网开发环境是不允许连接外网的,因此Python的很多依赖包都没有办法用pip安装,这一点让人很头疼。不过还好我遇到了Go语言。

出于我的学习初衷,我学习Go语言也是边翻书边敲代码,到现在也是写了几个小工具了,效果还不错。但是这种学习方式总是让基础比较薄弱,有些地方研究思考的不是很到位。

因此未来还是从最基础的变量等等学起吧。

相关文章

  • Go语言之通道(二)

    1. 前情回顾 Go语言提供了goroutine来简单的实现并发,对于我这种不太喜欢动脑子的人来说这是一个非常完美...

  • Go语言之通道(一)

    1. 开篇 我决定学习Go语言的时候,就做好了多线程编程的准备,而多线程编程,很重要的一点就是线程间通信。比如Ja...

  • Go语言之通道(三)

    通道是一个很重要的概念,用于goroutine间通信的,而且这种方式还能玩出很多新花样来,比如搞一个通道出来。下面...

  • Go语言之Interface(二)

    使用指针接收器和值接收器实现接口 实现多个接口 接口嵌套 在Go语言中没有继承的概念,但是通过组合可以实现继承的效...

  • 便捷golang开发

    go语言之旅:https://tour.go-zh.org/如何使用go编程:https://go-zh.org/...

  • 《Go语言四十二章经》第二十二章 通道(channel)

    《Go语言四十二章经》第二十二章 通道(channel) 作者:李骁 22.1 通道(channel) Go 奉行...

  • Go语言之“类”篇(二)

    前言介绍:本人原本是C++开发工程师,使用C++已经有8年多的时间,最近在学习Go语言,在学习Go语言的时候,难免...

  • go的通道

    注: 本笔记是自己的学习笔记,都是自己的理解,而不是教学文章,要学习请自行阅读 图书 --- Go程序设计语...

  • golang 创建DB连接池

    使用通道 自己写的连接池 db.go pool.go id生成器 使用

  • GO 中 defer的实现原理

    GO 中 defer的实现原理 我们来回顾一下上次的分享,分享了关于 通道的一些知识点 分享了 GO 中通道是什么...

网友评论

    本文标题:Go语言之通道(二)

    本文链接:https://www.haomeiwen.com/subject/nwyyaqtx.html