昨天需要一个线下脚本进行单播推送,大约有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";
#endifstruct 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();
}/**
* 请求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 -;
}
memset(ret, , 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[];
memset(buf, , );
pthread_t thid;
while(!feof(fp) && fgets(buf, , 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 != ){
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[];
int http_code = mapi_push(data, ret, );
if(http_code == ){
if(strncmp(ret, "{\"errno\":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);
}
其实还有好多可以优化的点,线下执行了一下,效果和速度还行