在多线程并发请求api的场景中,如何控制每个线程的qps

bai_jimmy bai_jimmy     2022-07-28     469

关键词:

想了一段时间,给出代码Demo

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef struct qps_s{
        int count;
        unsigned int second;
}qps_t;

pthread_key_t tdata;
qps_t qps_data;

int push_timestamp() {
        time_t tt;
        return time(&tt);
}

void *thread_data_del(void *tdata){
        if(tdata){
                free(tdata);
                printf("free
");
        }
}

void doing(){
        qps_t *qps_data = (qps_t *)pthread_getspecific(tdata);
        //说明还没有设置过
        if(!qps_data){
                qps_data = (qps_t *)calloc(1, sizeof(qps_t));
                qps_data->count = 0;
                qps_data->second = push_timestamp();
                pthread_setspecific(tdata, qps_data);
        }

        while(1){
                int now_time = push_timestamp();
                if(now_time == qps_data->second){
                        //触发了qps限制
                        if(qps_data->count >= 2){
                                usleep(10000);
                                continue;
                        }
                        //没有触发限制
                        else{
                                qps_data->count++;
                                break;
                        }
                }else{
                        //时间不相同,说明qps限制肯定没问题
                        qps_data->count = 1;
                        qps_data->second = now_time;
                        break;
                }

        }
        printf("request some api => %d, %d
", qps_data->second, qps_data->count);
}


void *worker(void *argv){
        int i;
        for(i = 0; i < 10; i++){
                doing();
        }
}

int main(){
        pthread_t pid1, pid2;
        pthread_key_create(&tdata, (void *)(void *)thread_data_del);

        pthread_create(&pid1, NULL, worker, NULL);

        pthread_join(pid1, NULL);
        pthread_key_delete(tdata);
        return 0;
}

 

效果

[[email protected] news_push/]valgrind --tool=memcheck ./a.out 
==31818== Memcheck, a memory error detector
==31818== Copyright (C) 2002-2013, and GNU GPLd, by Julian Seward et al.
==31818== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==31818== Command: ./a.out
==31818== 
request some api => 1467205046, 1
request some api => 1467205046, 2
request some api => 1467205047, 1
request some api => 1467205047, 2
request some api => 1467205048, 1
request some api => 1467205048, 2
request some api => 1467205049, 1
request some api => 1467205049, 2
request some api => 1467205050, 1
request some api => 1467205050, 2
free
==31818== 
==31818== HEAP SUMMARY:
==31818==     in use at exit: 0 bytes in 0 blocks
==31818==   total heap usage: 2 allocs, 2 frees, 280 bytes allocated
==31818== 
==31818== All heap blocks were freed -- no leaks are possible
==31818== 
==31818== For counts of detected and suppressed errors, rerun with: -v
==31818== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

 

在多线程或并发中控制事务的解决方案

...供数据的线程本地存储,其实通俗易懂的讲就是一个变量在多个线程中实现多个拷贝(副本),因为多线程的机制,各个线程的变量是互不影响的,所以不用担心 查看详情

jmeter按比例分配api压测

...发量呢?使用Jmeter可以有两种实现方式先说第一种,通过线程组的方式控制:线程组1配置: 线程组2配置: 区别就是线程数不一样,当然用循环次数也可以控制,区别可以看【Jmeter】基础介绍-详细。Request请求: 结... 查看详情

threadlocal详细解答(代码片段)

...#xff1a;ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是privatestatic类型的,用于关联线... 查看详情

jsch的sftp在多线程下的问题及处理办法

...技术ASftpUtil2:测试程序:该程序使用多线程并发操作sftp,在多线程中共用一个ChannelSftp,就会出异常,具体如下:在SftpUtil中使用ThreadLocal包装ChannelSftp、Session保证线程安全。在Test3中使用parallelStream().forEach完成多线程并发操作sftp。S... 查看详情

在多线程应用程序中控制对输出的访问

】在多线程应用程序中控制对输出的访问【英文标题】:Controllingaccesstooutputinmulti-threadedapplications【发布时间】:2010-01-0400:12:37【问题描述】:我有一个创建作业队列的应用程序,然后多个线程执行这些作业。通过执行它们,我... 查看详情

如何在jmeter中同时运行线程

】如何在jmeter中同时运行线程【英文标题】:Howtorunthreadsconcurrentlyinjmeter【发布时间】:2018-03-1206:48:29【问题描述】:您好,我创建了一个包含10个事务控制器的线程组,每个控件都有多个HTTP请求采样器。现在要根据需求确定瓶... 查看详情

springboot单例怎么实现并发请求处理的

并发的请求会在线程池中等待,每个线程调用单例bean(堆内存)的方法时,每个方法的数据存储在栈内存中(每个线程私有);线程池会配置最大连接数,请求量超过最大连接数时请求无效(服务器会拒绝连接);并发的线程... 查看详情

使用线程池时一定要注意的五个点

...须能够处理一系列传入请求,简单的处理方式是通过一个线程顺序的处理这些请求,如下图:单线程策略的优势和劣势都非常明显:优势:设计和实现简单;劣势:这种方式会带来处理效率的问题,单线程的处理能力是有限,不... 查看详情

java多线程并发编程-避坑指南

本篇旨在基于编码规范、工作中积累的研发经验等,整理在多线程开发的过程中需要注意的部分,比如不考虑线程池参数、线程安全、死锁等问题,将会存在潜在极大的风险。并且对其进行根因分析,避免每天踩一坑,坑坑不一... 查看详情

多线程场景设计利器:分离方法的调用和执行——命令模式总结(代码片段)

前言个人感觉,该模式主要还是在多线程程序的设计中比较常用,尤其是一些异步任务执行的过程。但是本文还是打算先在单线程程序里总结它的用法,至于多线程环境中命令模式的用法,还是想在多线程的设计模式里重点总结... 查看详情

高并发内存池(代码片段)

...身就已经很优秀了,那么我们的项目原型tcmalloc就是在多线程高并发的场景下更胜一筹,所以这次我们实现的内存池要考虑几个方面。性能问题在多线程下,锁竞争问题内存碎片问题concurrentmemorypool主要由下面3个部分... 查看详情

高并发内存池(代码片段)

...身就已经很优秀了,那么我们的项目原型tcmalloc就是在多线程高并发的场景下更胜一筹,所以这次我们实现的内存池要考虑几个方面。性能问题在多线程下,锁竞争问题内存碎片问题concurrentmemorypool主要由下面3个部分... 查看详情

jmeter如何控制线程执行?

首先明确如何管理线程执行--使用线程组实现--管理线程的的单位(针对线程按照性质分组管理的结果)--方便管理线程,控制线程执行其次,明确执行的顺序--线程执行顺序1.并发执行--多线程同时执行--线程启动和结束顺序不一致2.顺... 查看详情

并发问题

并发问题来自并发计算的场景,该场景下,程序在多线程(或多进程)中同时执行。同时进行并不是完全指进程或线程在不同的物理CPU上独立运行,更多情况下,是在一个物理CPU上交替执行多个线程或进程。并发既可在线程中,... 查看详情

并发场景

...享资源的并发访问,产生竞争。例如:操作系统,进程和线程对CPU资源的竞争获取生产者-消费者问题,比如队列读者-作者问题哲学家进餐问题客服分配问题,限制每个客服最多服务多少个用户,多余的用户只能排队线程池,比... 查看详情

如何保护可能在多线程或异步环境中使用的资源?

】如何保护可能在多线程或异步环境中使用的资源?【英文标题】:Howtoprotectresourcesthatmaybeusedinamulti-threadedorasyncenvironment?【发布时间】:2014-01-2711:17:01【问题描述】:我正在开发一个可供各种消费者使用的C#API。此API提供对共享... 查看详情

并发编程

...并行:多个线程在处理同一个操作 什么叫做并发编程:在多线程环境下,应用程序的执行 并发编程的目的:充分运用到资源,提高程序的效率 什么情况下用到并发编程:   1.在线程阻塞时,导致应用程序停止   2.处... 查看详情

在多线程 Java 程序中,每个线程是不是都有自己的 System.out 副本?

】在多线程Java程序中,每个线程是不是都有自己的System.out副本?【英文标题】:InamultithreadedJavaprogram,doeseachthreadhaveitsowncopyofSystem.out?在多线程Java程序中,每个线程是否都有自己的System.out副本?【发布时间】:2012-04-1809:37:16【... 查看详情