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

马谦马谦马谦
马谦马谦马谦
马谦马谦马谦
615
文章
12
评论
2017年11月29日20:34:10 评论

一、并发问题

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()来创建连接池,但是这个方法是不推荐的:

三、示例代码

一个完整的示例代码:

历史上的今天
11月
29
马谦马谦马谦
  • 本文由 发表于 2017年11月29日20:34:10
  • 转载请务必保留本文链接:https://www.dyxmq.cn/program/code/golang/golang-redigo-concuurent-and-connect-pool.html
redis源码分析:链表实现 Redis

redis源码分析:链表实现

一、链表定义 链表在redis中的使用十分广泛,例如列表的底层实现之一就是链表,包括发布、订阅等等功能都是有用到链表的。redis中链表在adlist.h和adlist.c中实现,只用了300+行代码...
国内几个优质的Go Module代理仓库服务 Golang

国内几个优质的Go Module代理仓库服务

一、简介 go module公共代理仓库,代理并缓存go模块。你可以利用该代理来避免DNS污染导致的模块拉取缓慢或失败的问题,加速你的构建。 简单来说就是国内访问被墙,go get无法在线获取到仓库,...
redis中的发布和订阅 Redis

redis中的发布和订阅

一、发布和订阅 除了任务队列以外,redis还有一种基于“发布/订阅”模式的消息传递,使得客户端可以订阅某个频道,当频道有消息产生时,会把消息传递到所有的订阅者。和列表不一样的是,发布和订阅可以是一对...
匿名

发表评论

匿名网友 填写信息

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