Golang redigo使用笔记(二):并发处理和连接池

马谦马谦马谦 2017年11月29日20:34:10 发表评论
文章最后编辑于:2017-12-4 19:19:29

一、并发问题

redigo官方的文档描述中,Receive()方法是不支持多并发的,原文为:

Do()方法是间接调用了Receive()方法,所以Do()方法也是不支持多并发的。我们可以用一段代码来验证这一点:

这里是一个函数,完成了一个简单的INCRBY命令,实现nKey + i功能,和正常情况不同的是在Send()Flush()后不会立刻使用Receive()来获取结果,而是让线程休眠一段时间再来获取。

主函数中开启两个gorutine运行这段代码:

运行结果:

可以看到,线程5先运行,然后线程1运行,由于线程1休眠时间短,所以它会先读取输入缓冲区的返回数据,按照预期,线程1读到的结果应该是1,因为它只是执行了incr nKey 1。而实际上,它读到的却是线程5的结果。

从这里我们可以很明显看出这一过程是线程不安全的,即它是不支持多并发的。那么如果要实现并发应该怎么做呢,官方也提出了解决方法,使用线程安全的连接池来解决这个问题:

二、连接池

redigo中的线程池是一个对象:

一个连接池创建的示例为:

当连接池创建完毕之后,如果需要使用连接时调用pool.Get()方法即可获得一个可用的连接,此时再执行Do()等方法时就不会被其他并发干扰,要注意的是每获取到一个可用的连接并且在使用完之后,一定要通过conn.Close()来主动释放连接,以方便下一个应用调用,不然该连接将会一直被占用。

同时官方提供了一个NewPool()来创建连接池,但是这个方法是不推荐的:

三、示例代码

一个完整的示例代码:

本文共执行41次查询,耗时0.303秒!
历史上的今天
十一月
29
马谦马谦马谦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: