我正在尝试实现一个令牌桶算法,我希望每隔x秒使用t令牌初始化我的令牌。让我们说每5秒我想用10来初始化令牌。如果5秒钟结束,那么再用10重新初始化我的令牌。
while(1)
{
if(/* 5 seconds are over, reinitialize the tokens with 10 */)
/* Initialize a variable */
token = 10; /* tokens are 5 */
else
token --;
}
我怎样才能做到这一点?
答案 0 :(得分:0)
假设你在Windows上,你可能想要考虑这样的解决方案:
uint32_t token;
time_t tokenInitialization;
time_t check;
token = 10;
time(&tokenInitialization);
while (1)
{
Sleep(1000);
time(&check);
if (difftime(check,tokenInitialization) >= 5)
{
printf("reinitializing.. %d\n",token);
time(&tokenInitialization);
/* 5 seconds are over, reinitialize the tokens with 10 */
/* Initialize a variable */
token = 10; /* tokens are 5 */
}
else
token--;
}
答案 1 :(得分:0)
在unix系统上,您可以使用警报系统。在此示例代码中,令牌是全局变量。为了便于携带,可能需要使用函数来获取时间的解决方案。我在这里展示了一种可能的报警机制解决方案。
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void reset_token(int);
int token;
int main () {
// Sets SIGALARM to be delivered to this process in 5 seconds
alarm(5);
// Sets our reset_token to be called each time
// a SIGALARM is received
signal(SIGALARM, reset_token);
token=10;
while(1) {
token--;
}
return(0);
}
void reset_token(int signum) {
// This function is called every time this process
// receives a SIGALARM. We reset the token here.
token=10;
// Sets SIGALARM to be delivered again in 5 seconds
alarm(5);
}
答案 2 :(得分:0)
特定于操作系统。如果您在没有操作系统的情况下运行,则它是特定于平台和硬件的。
对于Linux,请同时阅读time(7)并考虑timer_create(2)及其相关功能。 alarm(2)是旧式的(并且具有一秒钟的粒度;其他系统调用可以实现更小的定时器间隔,可能小于一毫秒)。
不要使用繁忙的等待循环:它们无用地运行CPU周期(因此消耗电力并加热处理器并吸取笔记本电脑电池)。使用一些空闲循环等待。您可以在某些事件循环中使用poll(2),或使用pause(2),nanosleep(2)等...
请务必阅读signal(7)和signal-safety(7)。如果你有一个信号处理程序,在其中设置一些你将在别处测试的volatile sig_atomic_t
标志。
了解volatile variables。你肯定需要使用一些(甚至在其他平台上)。您的token
变量很可能应该是volatile
。使用C11,也可以考虑atomic operations。
你也可以考虑一些多threaded方法。阅读一些Pthread tutorial并关注synchronization,atomicity,ACID - ity,mutexes,semaphores。