redis分布式锁的实现----C语言

EX和NX的区别 ex 设置键的过期时间为 second 秒。NX :只在键不存在时,才对键进行设置操作。 main.cpp #include "redis.

EX和NX的区别

ex 设置键的过期时间为 second 秒。NX :只在键不存在时,才对键进行设置操作。

main.cpp

#include "redis.h"
#include 
int main()
{Redis *r = new Redis();r->connectRedis("127.0.0.1",6379,5);while (r->tryLock(40) != 0){/* code */sleep(10);}return 0;
}

redis.h

#ifndef _REDIS_H_
#define _REDIS_H_#include 
#include 
#include 
#include #include class Redis
{
public:Redis();~Redis();int connectRedis(std::string addr, int port, int time_out);int tryLock(int duration);redisReply *ExecuteCmd(const char *cmd, char *data = NULL, int dataSize = 0);
private:redisContext *_connect;redisReply *_reply;private:int m_timeOutConnect;struct timeval m_tv; //redis  命令超时时间redisContext *m_redisContent;std::string m_redisIp;int m_redisPort;
};#endif //_REDIS_H_

redis.cpp

#include "redis.h"Redis::Redis() {}Redis::~Redis()
{this->_connect = NULL;this->_reply = NULL;
}int Redis::connectRedis(std::string addr, int port, int time_out)
{m_redisIp = addr;m_redisPort = port;int ret = -1;//struct timeval tv;m_tv.tv_sec = time_out;m_tv.tv_usec = 0;m_timeOutConnect = time_out;m_redisContent = redisConnectWithTimeout(m_redisIp.c_str(), m_redisPort, m_tv);if (m_redisContent == NULL){ret = -1;return ret;}else{if (m_redisContent->err != 0){std::cout << "connect redis ip:" << m_redisIp << ",port:" << m_redisPort << ",error:" << m_redisContent->errstr;ret = -1;redisFree(m_redisContent);m_redisContent = NULL;return ret;}}// ret = (int)authRedis();redisSetTimeout(m_redisContent, m_tv);redisEnableKeepAlive(m_redisContent);
}int Redis::tryLock(int duration)
{int ret = -1;char cmdBuf[256] = {0};sprintf(cmdBuf, "set %s %s ex %d nx", "gbdlock", "0.0.0.0", duration); //ex 设置键的过期时间为 second 秒。NX :只在键不存在时,才对键进行设置操作。redisReply *reply = ExecuteCmd(cmdBuf);if (reply && reply->type != REDIS_REPLY_NIL && strcmp(reply->str, "OK") == 0){ret = 0;std::cout << "redis set lock OK!!!"<< "0.0.0.0" << std::endl;}else{char cmdBuf1[256] = {0};/* get lock */sprintf(cmdBuf1, "GET %s", "gbdlock");reply = ExecuteCmd(cmdBuf1);if (reply && reply->type != REDIS_REPLY_NIL){if (reply->str && !strcmp("gbdlock", reply->str)){ret = 0;std::cout << "Get lock succ: integer = " << reply->integer << " str = " << reply->str;}}std::cout << "redis set lock fail!!!"<< "gbdlock" << std::endl;}if (reply != NULL){freeReplyObject(reply);}EXIT:return ret;
}redisReply *Redis::ExecuteCmd(const char *cmd, char *data, int dataSize)
{if (m_redisContent == NULL){std::cout << "Redis: m_redisContent == NULL error";return NULL;}redisReply *reply = NULL;if (data == NULL){reply = (redisReply *)redisCommand(m_redisContent, cmd);}else{if (dataSize > 2 * 1024 * 1024 /*一个二进制redis数据的最大长度*/){std::cout << "redis dataSize more then MAX_REDIS_BIN_LEN ";return NULL;}reply = (redisReply *)redisCommand(m_redisContent, cmd, data, dataSize);//redisReply *reply = (redisReply *)redisCommand(m_redisContent, "RPUSH %s %b", listName, data, dataSize);}return reply;
}

makefile

redis: main.cpp redis.cppg++ main.cpp redis.cpp -o test -L /usr/local/lib/ -lhiredis
clean:rm redis