简单流控--漏桶与令牌桶
漏桶示例:slowcat.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define READLENTH 10 //设置一次读取长度
static volatile int loop =1; //标志
static void alrm_handler(int s) //闹钟事件处理
{
alarm(1); //循环设置闹钟
loop = 0;
}
int main(int argc, char**argv)
{
int fd;
int readcnt;
int writecnt;
int pos;
char readbuff[READLENTH];
if(argc<2) //参数判断
{
fprintf(stderr,"Usage:%s <filename>\n",argv[0]);
exit(1);
}
signal(SIGALRM,alrm_handler); //注册信号处理函数
alarm(1); //创建闹钟信号
while(1)
{
fd = open(argv[1],O_RDONLY); //打开文件
if(fd <0 && errno !=EINTR) //当不是中断导致打开出错时
{
perror("open()");
exit(1);
}
else if(fd >=0) //正常打开
break;
}
while(1)
{
while(loop) //判断是否有闹钟事件到
pause();
loop = 1;
while((readcnt = read(fd, readbuff, READLENTH))<0) //读取数据
{
if(errno!=EINTR) //不为中断导致读取出错时
{
perror("read()");
exit(1);
}
else
continue;
}
if(readcnt ==0)
break;
pos = 0;
while(readcnt>0)
{
writecnt = write(1,readbuff+pos,readcnt); //向标准输出写入数据
if(writecnt<0) //写入错误时
{
if(errno == EINTR)
continue;
perror("write()");
exit(1);
}
pos +=writecnt;
readcnt -=writecnt;
}
}
close(fd);
exit(0);
}
令牌桶示例:slowcat2.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define READLENTH 10
#define MAXTOKEN 100 //最大令牌数
static volatile int token =0; //令牌数
static void alrm_handler(int s) //闹钟信号处理函数
{
alarm(1); //循环产生闹钟事件
token++; //令牌数自加
if(token>=MAXTOKEN) //限制令牌最大数
token == MAXTOKEN;
}
int main(int argc, char**argv)
{
int fd;
int readcnt;
int writecnt;
int pos;
char readbuff[READLENTH];
if(argc<2) //判断输入参数
{
fprintf(stderr,"Usage:%s <filename>\n",argv[0]);
exit(1);
}
signal(SIGALRM,alrm_handler); //注册闹钟处理函数
alarm(1); //创建闹钟
while(1)
{
fd = open(argv[1],O_RDONLY); //打开文件
if(fd <0 && errno !=EINTR)
{
perror("open()");
exit(1);
}
else if(fd >=0)
break;
}
while(1)
{
while(token<=0) //没有令牌数时
pause();
token--; //令牌数自减
while((readcnt = read(fd, readbuff, READLENTH))<0) //读取数据
{
if(errno!=EINTR)
{
perror("read()");
exit(1);
}
else
continue;
}
if(readcnt ==0)
break;
pos = 0;
while(readcnt>0) //循环写入数据
{
writecnt = write(1,readbuff+pos,readcnt);
if(writecnt<0)
{
if(errno == EINTR)
continue;
perror("write()");
exit(1);
}
pos +=writecnt;
readcnt -=writecnt;
}
}
close(fd);
exit(0);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现