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 ...
随机推荐
- 华东师范大学数学分析课本p294,引理3的我的更正证明
书上的证明是一个特例,我的证明是,如果这个特例不成立,就继续做n-1,直到特例的情况出现,即可.
- 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概览
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的基本特性. 恩智浦半导体于2017年开始推出的i.MX RT系列重新定义了MCU,其第一款芯片i. ...
- python基础day6_字典dict
数据类型划分:可变数据类型.不可变数据类型 不可变数据类型(又叫可哈希):元祖,bool ,int,str, 可变数据类型(又叫不可哈希):list,dict,set(集合) dict的key必须是不 ...
- PHP array_udiff_assoc() 函数
实例 比较两个数组的键名和键值(使用内建函数比较键名,使用用户自定义函数比较键值),并返回差集: <?phpfunction myfunction($a,$b){if ($a===$b){ret ...
- 4.23 子串 AC自动机 概率期望 高斯消元
考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...
- 有关WebSocket必须了解的知识
一.前言 最近之前时间正好在学习java知识,所以自个想找个小项目练练手,由于之前的ssm系统已经跑了也有大半年了,虽然稀烂,但是功能还是勉强做到了,所以这次准备重构ssm系统,改名为postCode ...
- [转]Nginx介绍-反向代理、负载均衡
原文:https://www.cnblogs.com/wcwnina/p/8728391.html 作者:失恋的蔷薇 1. Nginx的产生 没有听过Nginx?那么一定听过它的"同行&qu ...
- Spring中使用MyBatis Generator
简介 MyBatis Generator 是由MyBatis官方提供的MyBatis代码生成器.可以根据数据库表生成相关代码,比如POJO.Mapper接口.SQL Map xml等. 使用方式 MB ...
- beyond compare4 密钥 亲测可用
beyond compare4过了试用期: 密钥: w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv1BM3+H1XygMtiE0-J ...
- Android SP的具体内容
过了这么久了,看看自己的园龄都17天了,一直在总结,从未缺席,我还是很开心的,踏踏实实的完成自己能学到的. 今天学习SP SP:全称SharedPreferences,别问我为啥知道,因为打了好多遍了 ...