什麽是分布式鎖極速飛艇平臺開發
分布式鎖的本質可以看作是特殊的普通鎖,它的競爭者不是普通的進程和線程,它的競爭者分布在不同的主機上,需要通過網絡來相互通信,不同的主機分布和網絡的不確定性給分布式鎖的實現和普通鎖有著很大的不同。
什麽是分布式鎖極速飛艇平臺開發,需要請搜索【大神源碼論壇】dsluntan.com 客服企娥3393756370 V信17061863513,
基於redis實現分布式鎖很簡單,通過一個命令setnx(set if no exist).只有在key不存在的時候才set成功返回1,否則返回失敗0,但是要考慮到一些意外情況還是需要一個很嚴謹的邏輯。
//
// Created by dguco on 18-9-9.
//
#ifndef SERVER_REDI_LOCK_H
#define SERVER_REDI_LOCK_H
#include <iostream>
#include <redis_client.h>
#include <future>
using namespace std;
// 獲取當前秒數
int GetSecond()
{
struct timeval tmval = {0};
int nRetCode = gettimeofday(&tmval, NULL);
if (nRetCode != 0) {
return 0;
}
return (int) (tmval.tv_sec);
}
#define LOCK_TIME_OUT 1 //1s
CRedisClient g_RedisCli;
class CRedisLock
{
public:
/*
- @param lockKey
- @param isBlock 司機阻塞
- @return 是否鎖成功
bool Lock(std::string &lockKey, bool isBlock = false);
template<class F, class... Args>
void DoWithLock(std::string &lockKey, F &&f, Args &&... args);
template<class F, class... Args>
void TryDoWithLock(std::string &lockKey, F &&f, Args &&... args);
private:
int m_iLockTimeOut;
};
template<class F, class... Args>
void CRedisLock::TryDoWithLock(std::string &lockKey, F &&f, Args &&... args)
{
bool isLock = Lock(lockKey, false);
if (isLock) {
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
(*task)( );
int now = GetSecond( );
if (now < m_iLockTimeOut) {
g_RedisCli.Del(lockKey);
}
}
}
template<class F, class... Args>
inline void CRedisLock::DoWithLock(std::string &lockKey, F &&f, Args &&... args)
{
bool isLock = Lock(lockKey, true);
if (isLock) {
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
(*task)( );
int now = GetSecond( );
if (now < m_iLockTimeOut) {
g_RedisCli.Del(lockKey);
}
}
}
bool CRedisLock::Lock(std::string &lockKey, bool isBlock)
{
int lock = 0;
m_iLockTimeOut = 0;
bool isLock = false;
while (lock != 1) {
int now = GetSecond( );
m_iLockTimeOut = now + LOCK_TIME_OUT + 1;
lock = g_RedisCli.Setnx(lockKey, to_string(m_iLockTimeOut));
//是否獲取成功
if (lock == 1) {
isLock = true;
}
//判斷是否超時,並設置新的超時時間
if (!isLock) {
string res = "";
g_RedisCli.Get(lockKey, &res);
//如果沒有被其他競爭者
if (res != "") {
int out1 = atoi(res.c_str( ));
string res1 = "";
g_RedisCli.Getset(lockKey, &res1);
//如果更新超時之前沒有被其他競爭者搶先且超時
if (now > out1 && res == res1) {
isLock = true;
}
}
}
if (isLock or !isBlock) {
break;
}
else {
usleep(1000);
}
}
return isLock;
}
#endif //SERVER_REDI_LOCK_H
什麽是分布式鎖極速飛艇平臺開發