使用信号实现漏桶流量控制
实现流量控制,利用signal函数,模拟实现一个每隔1s打印文件10个字符内容到屏幕的功能
//案例代码
//slowcat.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
//定义每秒钟传输的字节个数
#define CPS 10
#define BUFSIZE CPS
static volatile int loop = 0;
static void alrm_handler(int s)
{
//当程序执行到此处,为自己下一次发送信号
alarm(1);
loop = 1;
}
int main(int argc,char*argv[])
{
int sfd,dfd = 1;
char buf[BUFSIZE];
int len,ret,pos;
if(argc < 2)
{
fprintf(stderr,"Usage......\n");
exit(1);
}
// 设置 SIGALRM 信号的处理函数为 alrm_handler
signal(SIGALRM,alrm_handler);
//1s发送一个alarm信号
alarm(1);
//打开要要读取的文件获得文件描述符sfd
do
{
sfd = open(argv[1],O_RDONLY);
if(sfd < 0)
{
if(errno != EINTR)
{
perror("open()");
exit(1);
}
}
}while(sfd < 0);
while(1)
{
while(!loop)//loop为0则在这死循环
pause();//一个系统调用,专门用来等待信号过来被打断的
loop = 0;
//从sfd读取BUFSIZE个字节内容到buf中
while((len = read(sfd,buf,BUFSIZE)) <0 )
{
//表示读取操作被中断。如当进程收到某个信号时,可能会导致 read() 操作被中断
if(errno == EINTR)
continue;
perror("read()");
break;
}
//len为0,说明读到文件末尾了,退出循环
if(len == 0)
break;
pos = 0;
while(len > 0)
{ //将buf中的内容输出到stdout上,因为dfd的值为1
while((ret = write(dfd,buf+pos,len)) <0 )
{
//假错,再继续读
if(errno == EINTR)
continue;
perror("write()");
exit(1);
}
pos += ret;
len -= ret;
}
}
close(sfd);
exit(0);
}