golang 并发demo 写入 redis
原文链接:golang 并发demo 写入 redis
源代码:
package main import (
"fmt"
"runtime"
"strconv"
"time" "gopkg.in/redis.v3"
) var (
jobnum = runtime.NumCPU()
//每次写入redis的数量
//除以 jobnum 为了保证改变了任务数, 总量不变, 便于测试
procnum = / jobnum
) type Job struct {
ID string
Client *redis.Client
Result chan<- string
} func waitJobs(dones <-chan struct{}, results chan string) {
working := jobnum
done := false
for {
select {
case result := <-results:
println(result)
case <-dones:
working--
if working <= {
done = true
}
default:
if done {
return
}
}
}
} func initClient(poolSize int) *redis.Client {
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DialTimeout: time.Second,
ReadTimeout: time.Second,
WriteTimeout: time.Second,
PoolSize: poolSize,
Password: "123.com",
DB: ,
})
if err := client.FlushDb().Err(); err != nil {
panic(err)
}
return client
} func main() {
start := time.Now()
fmt.Println("start:", start)
defer func() {
end := time.Now()
fmt.Println("end:", end)
fmt.Println("jobs num:", jobnum, "total items:", jobnum*procnum)
fmt.Println("total seconds:", end.Sub(start).Seconds())
}() //任务channel 定义缓冲器为job数量
jobs := make(chan Job, jobnum)
//存放结果
results := make(chan string, jobnum*procnum)
//每个任务完成之后给dones发送一次
dones := make(chan struct{}, jobnum) client := initClient()
defer client.Close() //定义每个任务执行的方法
jobfunc := func(client *redis.Client, id string) (string, error) {
defer func() {
//完成之后向 dones 发送数据
dones <- struct{}{}
//fmt.Println("job id:", id, "完成")
}() //写入 procnum 条数据
for idx := ; idx < procnum; idx++ {
key := id + "-" + strconv.Itoa(idx) _, err := client.Set(key, time.Now().String(), ).Result()
if err != nil {
return "", err
}
//fmt.Println("key:", key, " | result:", val, " | error:", err)
} return "ok", nil
} //1 添加 job 到 channel
go func() {
for index := ; index < jobnum; index++ {
jobs <- Job{strconv.Itoa(index), client, results}
}
defer close(jobs)
}() //2 并行执行 jobs
for j := range jobs {
go func(job Job) {
jobfunc(client, job.ID)
job.Result <- "ok"
}(j)
} //3 等待所有任务完成
waitJobs(dones, results)
}
运行结果:
[root@localhost ]# go run redis.go
start: -- ::34.614166323 + UTC m=+0.001802059
ok
ok
ok
ok
ok
ok
ok
ok
end: -- ::35.655656884 + UTC m=+1.043292369
jobs num: total items:
total seconds: 1.04149031
8 个 goroutine: 1s 完成10w数据写入
golang 并发demo 写入 redis的更多相关文章
- 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)
问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...
- Golang 并发简介
并发概要 随着多核CPU的普及, 为了更快的处理任务, 出现了各种并发编程的模型, 主要有以下几种: 模型名称 优点 缺点 多进程 简单, 隔离性好, 进程间几乎无影响 开销最大 多线程 目前使用最多 ...
- golang 并发锁的陷阱
错误代码示例 package main import ( "sync" "strconv" "fmt" ) type Node struct ...
- Golang - 并发编程
目录 Golang - 并发编程 1. 并行和并发 2. go语言并发优势 3. goroutine是什么 4. 创建goroutine 5. runtime包 6. channel是什么 7. ch ...
- 4种Golang并发操作中常见的死锁情形
摘要:什么是死锁,在Go的协程里面死锁通常就是永久阻塞了,你拿着我的东西,要我先给你然后再给我,我拿着你的东西又让你先给我,不然就不给你.我俩都这么想,这事就解决不了了. 本文分享自华为云社区< ...
- golang并发编程
golang并发编程 引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止go ...
- 马蜂窝搜索基于 Golang 并发代理的一次架构升级
搜索业务是马蜂窝流量分发的重要入口.很多用户在使用马蜂窝时,都会有目的性地主动搜索与自己旅行需求相关的各种信息,衣食住行,事无巨细,从而做出最符合需求的旅行决策. 因此在马蜂窝,搜索业务交互的下游模块 ...
- 批量写入redis
批量写入redis key := GetSeriesKey(series.Id) idNames = append(idNames, key, series.Name) == { err = Mset ...
- lua模块demo(redis,http,mysql,cjson,本地缓存)
1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...
随机推荐
- ffmpeg获取视频封面图片
ffmpeg百度云盘下载地址:https://pan.baidu.com/s/1Am_x0abBvXTrbCFPHs5e9Q 提取码:4y2r /** * ffmpeg百度云盘下载地址:https:/ ...
- mapstruct 实体转换及List转换,@Mapper注解转换
本文参考 https://blog.csdn.net/u012373815/article/details/88367456 主要是为了自己使用方便查询. 这些都是我平时用到了,大家有什么好方法或者有 ...
- 线程_Process基础语法
""" Process([group[,target[,name[,args[,kwargs]]]]]) group:大多数情况下用不到 target:表示这个进程实例所 ...
- PHP time_sleep_until() 函数
实例 延迟执行当前脚本直到 10 秒: <?php// wake up ten seconds from nowtime_sleep_until(time()+10);?>高佣联盟 www ...
- 7.18 NOI模拟赛 树论 线段树 树链剖分 树的直径的中心 SG函数 换根
LINK:树论 不愧是我认识的出题人 出的题就是牛掰 == 他好像不认识我 考试的时候 只会写42 还有两个subtask写挂了 拿了37 确实两个subtask合起来只有5分的好成绩 父亲能转移到自 ...
- mit-6.828 Lab01:Booting a PC exercise1.1
Lab01:Booting a PC 目录 Lab01:Booting a PC JOS BIOS 背景知识 8086的基本知识 GDB 常用调试指令 Real mode && Pro ...
- Linux常用命令之ls、cd、pwd、mkdir命令讲解
ls命令令是Linux最常用的命令之一,也是一条非常古老的命令.在开始学习Linux命令之前,还是想给大家一条建议: 很多同学可能刚开始学习Linux,然后就去买一些教材去学习,教材上面有可能收集了L ...
- cobbler多机定制安装
目录 cobbler多机定制安装 1. cobbler服务端部署 2. 客户端安装 3. 定制安装配置 4. 安装 client1开机 client2开机 cobbler多机定制安装 1. cobbl ...
- 【SDOI2010】猪国杀 题解(模拟)
前言:嗅到了一丝头秃的味道…… ------------------ 题目链接 题目实在太长,变量也很多.建议至少读个三五遍再做题.不要忽略任何细节,不要想当然.(因为真正玩三国杀肯定不像猪一样出牌啊 ...
- 2020牛客暑期多校训练营(第八场)K-Kabaleo Lite题解
K-Kabaleo Lite 题目大意: 给出每种菜品的利润以及碟数,要求我们给每个客人至少一碟菜,要求从1号菜品开始给,给的菜品的号码是连续的,每个客人同号码的菜都只能给一碟.求能招待客人的最大数量 ...