1. 程式人生 > >Golang基於redis實現的分散式訊號量(semaphore)

Golang基於redis實現的分散式訊號量(semaphore)

前言

Semaphore是訊號量,作用? 我想大家都知道。semaphore跟mutex的區別我想大家也知道了,我這裡就不老生常談,重複講解了,有興趣的朋友可以自行google相關的同步鎖文章。

像semaphore,mutex 可以支援多執行緒,也可以是多程序。但如果是在分散式叢集環境想實現類似 semaphore的東西怎麼做? 我們可以藉助redis來實現, 我這裡用了redis的hash、list、string實現的網路訊號量。 利用redis hash存token的時間,list用來實現堵塞及非阻塞模式,利用redis string的setnx來實現分散式鎖,鎖的目的是用來原子性寫一致。

該專案是使用golang寫的,再具體程式碼就不詳細描述了,有興趣的可以直接看程式碼。

github的專案地址:

https://github.com/rfyiamcool/go_redis_semaphore

用法

limiter := go_redis_semaphore.NewRedisSemaphore(redis連線池物件, 訊號量數目, "redis key的名字")

// 初始化redis
limiter.Init()

// 非阻塞拿鎖
token, _ := limiter.Acquire(0)

// 超時5s阻塞拿鎖
token, _ := limiter.Acquire(5)

// 釋放鎖
limiter.Release(token)

具體例子

package main
// xiaorui.cc

import (
	"fmt"
	"github.com/rfyiamcool/go_redis_semaphore"
)

func main() {
	fmt.Println("例項化redis連線池")
	redis_client_config := go_redis_semaphore.RedisConfType{
		RedisPw:          "",
		RedisHost:        "127.0.0.1:6379",
		RedisDb:          0,
		RedisMaxActive:   100,
		RedisMaxIdle:     100,
		RedisIdleTimeOut: 1000,
	}
	redis_client := go_redis_semaphore.NewRedisPool(redis_client_config)

	fmt.Println("例項化 redis Semaphore")
	limiter := go_redis_semaphore.NewRedisSemaphore(redis_client, 2, "love")
	limiter.Init()

	fmt.Println("非阻塞拿鎖")
	token, _ := limiter.Acquire(0)

	fmt.Println("釋放鎖")
	limiter.Release(token)
	fmt.Println(limiter.ScanTimeoutToken())
	fmt.Println("end")
}

END.