当前位置: 首页 > news >正文

令牌桶C语言代码实现

令牌桶实例

令牌桶三要素

cps 每秒钟传输字节数

burst 令牌桶内最多能传输的字节数,token的最大值

token 令牌的个数

之前是一个令牌(token)对应一个字节,现在将一个token变为一个cps,cps是解码速率,每攒到一个令牌,就token+=cps

不同的速率使用不同的令牌桶,将令牌桶存储在一个数组中。

代码

mytbf.h

#ifndef MYTBF__H_
#define MYTBF__H_#define MYTBF_MAX	1024
typedef void mytbf_t;mytbf_t *mytbf_init(int cps,int burst);int mytbf_fetchtoken(mytbf_t * ,int);int mytbf_returntoken(mytbf_t * ,int );int mytbf_destroy(mytbf_t *);#endif

mytbf.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>#include "mytbf.h"typedef void (*sighandler_t)(int);//将令牌桶的数据结构存在数组中
static struct mytbf_st * job[MYTBF_MAX];
static int inited = 0;
#define MIN(A,B) (A < B ? A : B)
static sighandler_t alrm_handler_save;/*每个token代表一个字节,cps代表解码速率,burst应该是cps的倍数,token=token+cps*/
//这是令牌桶的数据结构,这个数据结构存在数组中
struct mytbf_st 
{int cps;	//每秒钟传输的字节数int burst;	//令牌桶中令牌最大数量int token;	//令牌的个数int pos;	//记录令牌桶在数组的位置下标
};//信号捕捉函数
static void alrm_handler(int s)
{alarm(1);//为数组中的令牌桶中的令牌做累计for(int i = 0;i < MYTBF_MAX; i++){if(job[i] != NULL){job[i]->token += job[i]->cps;if(job[i]->token > job[i]->burst)job[i]->token = job[i]->burst;}}
}
//关闭时钟发送信号,恢复
static void module_unload(void)
{int i;//恢复SIGALRM到之前的功能signal(SIGALRM,alrm_handler_save);//取消时钟发送信号alarm(0);//释放令牌桶for(i = 0;i < MYTBF_MAX;i++){free(job[i]);}}
//第一次发时钟信号的函数
static void module_load(void)
{//signal的返回值是注册新的行为之前的行为alrm_handler_save = signal(SIGALRM,alrm_handler);alarm(1);//注册钩子函数,这个不是函数调用,而是当调用exit的时候才会调用atexit(module_unload);
}static int get_free_pos(void)
{int i = 0;for(i = 0;i < MYTBF_MAX; i++){if(job[i] == NULL)return i;}return -1;
}mytbf_t *mytbf_init(int cps,int burst)
{int pos = 0;struct mytbf_st *me;//在数组中找到空位下标pospos = get_free_pos();if(pos < 0){return NULL;}if( !inited ){module_load();inited = 1;}me = malloc(sizeof(*me));if(me == NULL){return NULL;}//初始化令牌桶结构体成员me->token = 0;me->cps = cps;me->burst = burst;me->pos = pos;//将令牌桶放到数组中job[pos] = me;return me;
}//取令牌
int mytbf_fetchtoken(mytbf_t *ptr ,int size)
{int n;struct mytbf_st *me = ptr;if(size <= 0)return -1;while(me->token <= 0)pause();//当要取的令牌数大于最大令牌数量,给最大令牌数量n = MIN(me->token,size);me->token -=n;return n;}//归还令牌
int mytbf_returntoken(mytbf_t *ptr ,int size)
{struct mytbf_st *me = ptr;if(size <=0 )return -1;me->token +=size;if(me->token > me->burst)me->token = me->burst;return size;
}//销毁令牌桶
int mytbf_destroy(mytbf_t *ptr)
{	//因为mytbf_t 是void类型,转换下struct mytbf_st *me = ptr;job[me->pos] = NULL;free(me);return 0;
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include "mytbf.h"#define CPS	    10
#define BUFSIZE	1024
#define BURST   100int main(int argc,char**argv)
{int sfd,dfd = 1;int size,errnor;char buf[BUFSIZE];int len,ret,pos;mytbf_t * tbf;if(argc < 2){fprintf(stderr,"Usage ....\n");exit(1);}//初始化令牌桶tbf = mytbf_init(CPS,BURST);//打开要读取的文件do{sfd = open(argv[1],O_RDONLY);if(sfd < 0){if(errno != EINTR){perror("open()");exit(1);}}}while(sfd < 0);while(1){size = mytbf_fetchtoken(tbf,BUFSIZE);if(size < 0){fprintf(stderr,"mytbf_fetchtoken is error\n");exit(1);}while((len = read(sfd,buf,size)) < 0){if(errno == EINTR)continue;perror("read()");break;}if(len == 0)break;//判断令牌是否用完if(size - len > 0)mytbf_returntoken(tbf,size-len);pos = 0;//使用循环读,因为是向终端写while(len > 0){ret = write(dfd,buf+pos,len);if(ret < 0){	//假错,继续读if(ret == EINTR)continue;perror("write()");exit(1);}pos += ret;len -= ret;}}mytbf_destroy(tbf);exit(0);
}

makefile

all:mytbf
mytbf:main.o mytbf.ogcc $^ -o $@
clean:rm *.o mytbf

相关文章:

令牌桶C语言代码实现

令牌桶实例 令牌桶三要素 cps 每秒钟传输字节数 burst 令牌桶内最多能传输的字节数&#xff0c;token的最大值 token 令牌的个数 之前是一个令牌(token)对应一个字节&#xff0c;现在将一个token变为一个cps&#xff0c;cps是解码速率&#xff0c;每攒到一个令牌&#xff…...

Mybatis 建立依赖失败:报错Dependency ‘mysql:mysql-connector-java:8.0.28‘ not found

Mybatis 建立依赖失败&#xff1a;报错Dependency ‘mysql:mysql-connector-java:8.0.28’ not found 解决办法&#xff1a; 写完依赖代码&#xff0c;直接重构&#xff0c;下载依赖。 图片: ![Alt](https://img-home.csdnimg.cn/images/20220524100510.png Mac 版本注意Ide…...

多线程+隧道代理:提升爬虫速度

在进行大规模数据爬取时&#xff0c;爬虫速度往往是一个关键问题。本文将介绍一个提升爬虫速度的秘密武器&#xff1a;多线程隧道代理。通过合理地利用多线程技术和使用隧道代理&#xff0c;我们可以显著提高爬虫的效率和稳定性。本文将为你提供详细的解决方案和实际操作价值&a…...

使用@Configuration和@Bean给spring容器中注入组件

Confguration->告诉spring这是一个配置类 以前我们是使用配置文件来注册bean的&#xff0c;现如今可以用Configuration 来代替配置文件。 //配置配配置文件 Configuration // 告诉Spring这是一个配置类,等同于以前的配置文件 public class MainConfig {// Bean注解是给IOC…...

信号波形解读

can波形解读 实际波形 标准帧 发送数据 仲裁段 0x1AA 数据长度为8字节 内容为&#xff1a;0x41, 0x20, 0x38, 0x41, 0x00, 0x16, 0x00, 0x00 波特率 111K...

Centos 解决 XXX不在 sudoers 文件中。此事将被报告。的错误

本来想使用 sudo 拷贝一个文件&#xff0c;结果出现上面的问题&#xff01; 下面是解决方法&#xff1a; 首先登录root&#xff0c;然后执行下面的命令 vim /etc/sudoers 将你需要添加的用户带红色框线的地方&#xff0c;模仿root写一遍&#xff0c;然后保存&#xff01; …...

雪花算法和uuid的区别

雪花算法&#xff08;Snowflake Algorithm&#xff09;和 UUID&#xff08;Universally Unique Identifier&#xff09;都是用于生成唯一标识符的方法&#xff0c;但它们在实现和适用场景上存在一些区别。 雪花算法&#xff1a; 雪花算法是Twitter开发的一种分布式ID生成算法…...

docker之DockerFile与网络

目录 DockerFile 构建步骤 基础知识 指令 实战&#xff1a;构建自己的centos 第一步&#xff1a;编写dockerfile文件 第二步&#xff1a;构建镜像文件 docker网络 原理 功能 网络模式 host模式 container模式 none模式 bridge模式 DockerFile dockerfile 是用来…...

知识蒸馏开山之作(部分解读)—Distilling the Knowledge in a Neural Network

1、蒸馏温度T 正常的模型学习到的就是在正确的类别上得到最大的概率&#xff0c;但是不正确的分类上也会得到一些概率尽管有时这些概率很小&#xff0c;但是在这些不正确的分类中&#xff0c;有一些分类的可能性仍然是其他类别的很多倍。但是对这些非正确类别的预测概率也能反…...

centos 7 安装 docker-compose curl 设置代理

sudo curl -x “http://192.168.1.2:3128” 需要验证的代理 sudo curl -x “http://username:password192.168.1.2:3128” 1.下载 sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/lo…...

3D姿态相关的损失函数

loss_mpjpe: 计算预测3D关键点与真值之间的平均距离误差(MPJPE)。 loss_n_mpjpe: 计算去除尺度后预测3D关键点误差(N-MPJPE),评估结构误差。 loss_velocity: 计算3D关键点的速度/移动的误差,评估运动的平滑程度。 loss_limb_var: 计算肢体长度的方差,引导生成合理的肢体长度…...

ChatGPT取代人类仍然是空想?有没有一种可能是AI在迷惑人类

ChatGPT自从去年发布以来&#xff0c;就掀起了这些大语言模型将如何颠覆一切的激烈讨论&#xff0c;从为学生写作文、输出SEO文章&#xff0c;甚至取代谷歌成为世界上最受欢迎的搜索引擎&#xff0c;影响领域无所不包&#xff0c;甚至可能取代编剧、小说家和音乐家等从事创意工…...

基于swing的旅游管理系统java jsp旅行团信息mysql源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 基于swing的旅游管理系统 系统有1权限&#xff1a;管…...

Windows wsl2支持systemd

背景 很多Linux发行版都是使用systemd来管理程序进程&#xff0c;但是在WSL中默认是用init来管理进程的。 为了符合长久的使用习惯&#xff0c;且省去不必要的学习成本&#xff0c;就在WSL的发行版&#xff08;我这里安装的是Ubuntu20.04&#xff09;中支持systemd&#xff0…...

NLP - 如何解决ModuleNotFoundError: No module named ‘jieba‘的问题

错误描述 在JUPYTER中&#xff0c;使用结巴分词&#xff0c;出错&#xff1a; ModuleNotFoundError: No module named jieba解决方案 在 Anaconda Prompt 中&#xff0c;执行以下指令&#xff08;可以解决&#xff09;&#xff1a; pip install jieba -i https://pypi.tuna…...

Windows10上VS2022单步调试FFmpeg 4.2源码

之前在 https://blog.csdn.net/fengbingchun/article/details/103735560 介绍过通过VS2017单步调试FFmpeg源码的方法&#xff0c;这里在Windows10上通过VS2022单步调试FFmpeg 4.2的方法&#xff1a;基于GitHub上ShiftMediaProject/FFmpeg项目&#xff0c;下面对编译过程进行说明…...

【tkinter 专栏】菜单组件

文章目录 前言本章内容导图1. Menu 菜单组件Menu 组件的基本使用制作二级下拉菜单为菜单添加快捷键2. Treeview 树形菜单组件Treeview 组件的基本使用菜单项的获取与编辑前言 本专栏将参考《Python GUI 设计 tkinter 从入门到实践》书籍(吉林大学出版社 ISBN: 9787569275001)…...

【LeetCode-经典面试150题-day10】

目录 242.有效的字母异位词 49.字母异位词分组 202.快乐数 219.存在重复元素Ⅱ 383.赎金信 205.同构字符串 290.单词规律 242.有效的字母异位词 题意&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和…...

Transformer在医学影像中的应用综述-分类

文章目录 COVID-19 Diagnosis黑盒模型可解释的模型 肿瘤分类黑盒模型可解释模型 视网膜疾病分类小结 总体结构 COVID-19 Diagnosis 黑盒模型 Point-of-Care Transformer(POCFormer)&#xff1a;利用Linformer将自注意的空间和时间复杂度从二次型降低到线性型。POCFormer有200…...

新服务器基本环境下载conda + docker + docker-compose + git

文章目录 Ubuntu 允许root用户登录 centos无所谓condadockerubuntucentos docker-compose官方下载docker-compose国内镜像 gitUbuntuCentos Ubuntu 允许root用户登录 centos无所谓 # 以普通用户登录系统&#xff0c;创建root用户的密码 sudo passwd root# SSH 放行 sudo sed -…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...