bai_jimmy

导航

多线程进行http请求

昨天需要一个线下脚本进行单播推送,大约有1kw个用户,考虑到推送速度就临时搞了个请求线上的一个脚本

 

/**
 * 临时支持invoke单播推送
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "ghttp.h"

#include "log.h"

//调试模式
#define DEBUGS
//最大线程数
#define MAX_THREADS 30

#ifndef DEBUGS
char *global_uri = "xxx";
#else
char *global_uri = "xxx";
#endif

struct active_t{
        pthread_mutex_t active_mutex;
        pthread_cond_t active_cond;
        int active;
}active_struct;

const char *global_request_conf = "conf/request.conf";

void *work_fun(void *arg);

static void _init_main(){
        open_log();
        print_log(DEBUG, "%s", "start...");
}

static void _shut_down(){
        print_log(DEBUG, "%s", "end...");
        close_log();
}

static void error_die(const char *msg){
        perror(msg);
        exit(1);
}

/**
 * 请求mapi
 */
int mapi_push(char *data, char *ret, int ret_len){
        ghttp_request *request = NULL;
        request = ghttp_request_new();
        ghttp_set_uri(request, global_uri);
        ghttp_set_type(request, ghttp_type_post);
        ghttp_set_header(request, http_hdr_Connection, "close");
        ghttp_set_header(request, http_hdr_Content_Type, "application/x-www-form-urlencoded");
        ghttp_set_body(request, data, strlen(data));
        ghttp_prepare(request);
        int status = ghttp_process(request);
        if(status == ghttp_error){
                return -1;
        }
        memset(ret, 0, ret_len);
        strncpy(ret, ghttp_get_body(request), ghttp_get_body_len(request));
        ret[strlen(ret)] = '\0';
        int http_code = ghttp_status_code(request);
        ghttp_request_destroy(request);
        return http_code; 
}

int main(){
        _init_main();

        FILE *fp = fopen(global_request_conf, "r");
        if(!fp){
                error_die("fopen error");
        }
        char buf[2048];
        memset(buf, 0, 2048);
        pthread_t thid;
        while(!feof(fp) && fgets(buf, 2047, fp) != NULL){
                //max thread
                pthread_mutex_lock(&active_struct.active_mutex);
                while(active_struct.active >= MAX_THREADS){
                        pthread_cond_wait(&active_struct.active_cond, &active_struct.active_mutex);
                }
                pthread_mutex_unlock(&active_struct.active_mutex);
                //run
                pthread_create(&thid, NULL, work_fun, (void *)buf);
                if(!thid){
                        printf("create thread error");
                        continue;
                }
                /*active+1*/
                pthread_mutex_lock(&active_struct.active_mutex);
                active_struct.active++;
                pthread_mutex_unlock(&active_struct.active_mutex);
        }
        //wait for all thread done
    pthread_mutex_lock(&active_struct.active_mutex);
    while(active_struct.active != 0){
        pthread_cond_wait(&active_struct.active_cond, &active_struct.active_mutex);
    }
    pthread_mutex_unlock(&active_struct.active_mutex);
        //clear
        _shut_down();
}

/**
* thread fun
*/
void *work_fun(void *arg){
        char *data = (char *)arg;
        pthread_detach(pthread_self());
        char ret[2048];
        int http_code = mapi_push(data, ret, 2048);
        if(http_code == 200){
                if(strncmp(ret, "{\"errno\":0", 10) != 0){
                        print_log(DEBUG, "errno:[2] http_cdoe:[%d] data:[%s] ret:[%s]", http_code, data, ret);
                }
        }else{
                print_log(DEBUG, "errno:[1] http_cdoe:[%d] data:[%s] ret:[%s]", http_code, data, ret);
        }

        //printf("%d, %s, %s\n", http_code, data, ret);
        //notice main thread
        pthread_mutex_lock(&active_struct.active_mutex);
        active_struct.active--;
        pthread_cond_signal(&active_struct.active_cond);
        pthread_mutex_unlock(&active_struct.active_mutex);
}

 其实还有好多可以优化的点,线下执行了一下,效果和速度还行

posted on 2016-02-02 14:15  bai_jimmy  阅读(6727)  评论(0编辑  收藏  举报