Exponetial BackOff(指数退避算法)


一:介绍

     指数退避算法的定义和使用可以在网上搜搜。提供一下wiki的介绍部分定义:an algorithm that uses feedback to multiplicatively decrease the rate of some process, in order to gradually find an acceptable rate.

    这边我介绍的是,指数退避的算法其实不只可以在网络包的重传机制中实现网络包的合理的重传机制。而且可以封装好相应的接口,从而利用这样的接口产生任何一种你需要的时间,或者你需要的重传的计数等。这些的应用只是利用了指数退避算法的本质,即根据要求产生需要的范围内的一个随机数,供需要的Action调用

二:C代码的实现封装的接口

   网上有很多只是介绍了指数退避算法的定义,和一份blog的伪代码和Javacode的实现。然后就是更种Copy了。这里上了部分笔记和C封装的代码,这样的接口调用,根据接口里的注释,可以做一定的修改,然后可以产生一个你需要的指数的随机数,供你程序的动态的使用。

/*
  the pesudocode 
  	Do some asynchronous operation:
  	retries = 0
  	Do 
  		wait for (2^retries * 100) milliseconds
  		status = Get the result of the asynchronous operation
  		If satatus = Success 
  			retry = False
  		Else If status = Not_Ready 
  			retry = true
  		Else if satus = Throttled 
  			retry = true 
  		Else
  			som other error occurrred, so stop calling the API	
  			retry = false 
  		End if
  		retries = retries + 1
  	While(retry AND (reties < MAX_RETRIES))
*/

#include <math.h>

/* Define the status of the retry  
** The flag of the result you can define as you need
**
***/
typedef ResStaus
{
	eRES_None,
	eRES_Success,
	eRES_OtherError
}st_ResStatus;

/* The MinTime Your action need to be active */
#define MAX_ACTIVE_TIME 100
#define MAX_ACTIVE_RETRIES 16

/* The times of exponential backoff */
double getWaitTimeExp(int RetryCount, long BaseTimes)
{
	double TempWait = 0;
	TempWait = (pow(2, RetryCount) * BaseTimes);
	return TempWait;
}

/* The operations */
int OperationWaitForResult()
{
	long Token = 0;
	int Retries = 0;
	bool RetryFlag = false;
	
	st_ResStatus Result = eRES_None;
	/* The BaseTime is the one times your action need to active */
	double BaseTimes = 0;
	double WaitTime = 0;
	
	do
	{
		/* Get the waittime times first */
		WaitTime = (MIN_ACTIVE_TIME > getWaitTimeExp(RetryCount, BaseTimes) ? 
					getWaitTimeExp(RetryCount, BaseTimes) : MAX_ACTIVE_TIME);
		
		printf("WaitTime :%ld\n", WaitTime);
		
		/* The thread hangup waittime */
		sleep(WaitTime);
		
		/* Your action functions return the status of the executed the functions */	
		Result = YourActionFunc();
		
		switch(Result)
		{
			/* Do your actions process */
			case eRES_Success:
				RetryFlag = false;
				break;
			
			/* Do your cation the error process */
			case eRES_OtherError:
				RetryFlag = true;
				break;
			
			default:
				/* The stop flag of your action need to process */
				break;
		}
		
	}while(RetryFlag && ((Retries++) < (MAX_ACTIVE_RETRIES))
	
	/* Do your later process */	
}
   其实这里面的精华部分,就是取得指数规避的动态的指数参数,并且这个返回的Times, 你可以用在定时器,或者你需要重复调用的Action的限制的时间,次数等。

三:实例的介绍

   这里具体的代码就不上了,不过提供一个思路。比如你想定时的去做一action,但是随着不同的返回值(程序接口运行的状态)你想动态的合理的规划定时器的调用时间,你就可以按照上面的指数退避的接口,产生一个合理的指数Times,然后设定一个最大,最小值,然后将此接口获得值提供给定时器的超时时间。这样可以合理的利用定时器的资源,从而使你的代码达到一种合理的利用资源的效果。其他的比如你重新注册等。这里的时间或许你可以在各个方面去实现,这样你不只在使用指数,其他的一些实用都可以应用。


四:Given a method to gerenated a uniforms times

    这里直接上了参照wiki的方法,代码和对应的算法公式。只需将上面的codes funcation 进行一些改变就可以了:

    

/*
	Give the uniform distribution of backoff times 
	The expected backoff time is the mean of the possibilities.That is ,after c collisions,
	the number of backoff slots is in [0, 1, ..., N], where N = 2^c -1 and 
	the expected backoff time (in lsots) is 
	(1)/(N + 1)(Sigma(1 -- N))
	
	for example:
		when c = 3;
		N = 2^C - 1;
		N = 7;
		and the calculate the mean of the back off time possibilities 
		E(c) = (1)/(N + 1)(Sigma(1 -- N))
			= N / 2 = (2^C - 1) / 2;
		
		which is, for the example, E(3) = 3.5 slots
*/
/* The times of exponential backoff */
double getWaitTimeExp(int RetryCount, long BaseTimes)
{
	double TempWait = 0;
	TempWait = (pow(2, RetryCount) * BaseTimes);

	/* Give the uniform distribution of backoff times */
	TempWait = (TempWait - 1) / 2;
	
	return TempWait;
}

  这样每次产生的time,就是一个唯一的Uniform time .

 
以上的仅供参考,欢迎指教


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值