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

Posted bai_jimmy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在多线程并发请求Api的场景中,如何控制每个线程的qps相关的知识,希望对你有一定的参考价值。

想了一段时间,给出代码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\n");
        }
}

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\n", 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)

 

以上是关于在多线程并发请求Api的场景中,如何控制每个线程的qps的主要内容,如果未能解决你的问题,请参考以下文章

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

ThreadLocal 详解并发容器

如何解决多线程高并发场景下的 Java 缓存问题?

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

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

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