归档 2010年10月

最后更新于 .

最近需要给一个现网server增加过载保护的功能,借此机会也思考了很多,简单谈谈我对这两个概念的理解和实现方法。
一.负载均衡
简单来说,就是按照目标server的参数进行合理分配,这个参数可以是失败率,也可以是响应时间,也可以是请求量,甚至是随机数。
我们来按照从简单到复杂逐个看一下几种实现。
1.轮询式
逻辑比较简单,直接看代码:


vector vecServer;
while(1)
{
Server* server = vecServer[curIndex % vecServer.size()];
curIndex ++;
}

如上代码就是一个简单的轮询式分配方法,这种方法优点实现简单,cpu计算少,缺点就是无法动态判断server的状态,当后端有一台server挂掉的时候,会至少1/vecServer.size()的请求。(最为严重的情况是由于单台后端server的超时导致前段全部挂死)。而且这种分配方法有一个bug,就是当每次请求结束后就释放内存,那么curIndex永远都只会为0,即每次都请求第一个server。

2.定死权重式

这种方式适用于那种需要实现就规定后端server的权重,比如A比Bserver的响应速度快,我们希望A接受的请求比B多。


//假设A,B, C server的权重分别为 10 5 2
typedef struct ...

最后更新于 .

在C/C++中,我们存储时间时,一般都会使用unix时间戳,使用也非常简单:


time_t t = time(NULL);

关于用C++实现string和time_t的转化,本博也专门写了一篇文章:

时间time_t和string(char*)格式互转

但是在python中怎么实现操作unix时间戳呢?

本博也特意写了代码如下:


# -*- coding: utf-8 -*-

import time
import datetime

def StringToTime(strtime):
t_tuple = time.strptime(strtime,"%Y-%m-%d %H:%M:%S")
return time.mktime(t_tuple)

def StringToTime2(strtime):
dt = datetime.datetime.strptime(strtime,"%Y-%m-%d %H:%M:%S ...

最后更新于 .

python,c#,java里面都有类似于foreach的结构,stl里面虽然有for_each这个函数,但是感觉使用还是太繁琐了一些,所以就自己实现了一个。 先来看看stl里面的for_each函数,官方文档上的原型如下:


Function for_each (InputIterator first, InputIterator last, Function f);

示例代码如下:


// for_each example
#include
#include
#include
using namespace std;

void myfunction (int i) {
cout << " " << i;
}

struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;

int main () {
vector myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);

cout << "myvector contains:";
for_each (myvector.begin ...

最后更新于 .

在python,c#等语言中,string都是默认提供split这个函数的,C++里面却没有默认实现,但又经常会用到,所以就简单实现了一个:


int SplitString(const string &srcStr,const string &splitStr,vector &destVec)
{
if(srcStr.size()==0)
{
return 0;
}
size_t oldPos,newPos;
oldPos=0;
newPos=0;
string tempData;
while(1)
{
newPos=srcStr.find(splitStr,oldPos);
if(newPos!=string::npos)
{
tempData = srcStr.substr(oldPos,newPos-oldPos);
destVec.push_back(tempData);
oldPos=newPos+splitStr.size();
}
else if(oldPos<=srcStr.size())
{
tempData= srcStr.substr(oldPos);
destVec.push_back(tempData ...

最后更新于 .

之前用mysql的时候一直是在用短链接,调用mysql_store_result获取一次数据之后就直接调用:


mysql_free_result(m_result);
mysql_close(m_Database);

但是有两个问题:

1.当使用长连接时(即connect之后一直不close),如果最后会调用mysql_close,需不需要每次都调用mysql_free_result呢?

2.当mysql_close调用之后,m_result的数据是否还可以用。

先说一下结论:
1.必须每次调用。因为经过测试,每次mysql_store_result的指针都是不同的,可见并不是共享了同一块buf。

2.还是可以使用。经过valgrind扫描,只调用mysql_close的扫描结果是:


==9397== 16,468 (88 direct, 16,380 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 5
==9397== at 0x40219B3: malloc (vg_replace_malloc.c:195)
==9397== by ...

最后更新于 .

一般来说,函数指针的用法是比较简单的。 比如对于函数:


int innerFunc(int num);

可以使用:


int (*ptrFunc)(int);
ptrFunc = innerFunc;//或&innerFunc

或者为了复用:

typedef int (*FUNC)(int);
FUNC ptrFunc;
ptrFunc = innerFunc;//或&innerFunc

但是当你使用类成员函数指针的时候,会发现完全不是那么一回事!而我今天就杯具的遇上了。。

废话不多说,直接上代码吧


#include
#include
#include
#include
using namespace std;

class Foo
{
public:
string m_str;
Foo()
{
m_str = "";
}
void test(char* str,int num)
{
m_str = str;
int (Foo::*ptrFunc)(int);

ptrFunc = &Foo::innerFunc;
//(*ptrFunc)(num);
//(this->(*ptrFunc))(num);
(this->*ptrFunc)(num);
}
int innerFunc(int num)
{
cout< cout< }
};

int ...

最后更新于 .

这是之前朋友出的一道题目,感觉不错,就拿来分享一下。
问题如下:
一个单向链表,怎么判断他是否存在环?

图示:

show

对于最简单的做法就是:
用一个指针走一圈,如果重复遇到其他任何一个指针,则证明有环。
但是这样做的问题就是:

单指针需要留下脚印,会弄脏链表数据,而如果不能脏数据的话,就需要增加一个容器,并且增加查找的开销。

有没有更好的方法呢?有的,定义一对快慢指针分别为ptr_fast,ptr_slow,ptr_slow走一步,ptr_fast走两步,如果ptr_slow和ptr_fast最终能相遇,那么证明有环。

解释如下:
画图:

show2

设步长分别为x和y,链表回环结点数为n,非环回环为m
设经过t次跨步,则只要xt和yt对n同余并且xt和yt都大于m就可以相遇(假设x>y)

xt-yt=pn
yt>m

得到:
t=pn/(x-y) > m/y(只需pn可整除(x-y))

指针移动次数为(x+y)t=(x+y)/(x-y)*pn

而要想pn永远整除(x-y ...

每日归档

上个月

2010年9月

下个月

2010年11月

归档