昨天需要一个线下脚本进行单播推送,大约有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();
} /**
* 请求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);
}

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

多线程进行http请求的更多相关文章

  1. GCD使用dispatch_semaphore_t创建多线程网络同步请求

    一.简介: dispatch_semaphore_t:表示信号,生成信号的方法是 dispatch_semaphore_t semaphore= dispatch_semaphore_create(0 ...

  2. 多线程时,请求执行不是按顺序的,可添加Critical Section Controller(临界部分控制器),执行顺序是固定的,但执行一段时间后,该逻辑器下的请求不再循环,无解ing

  3. 用Python写的一个多线程机器人聊天程序

    本人是从事php开发的, 近来想通过php实现即时通讯(兼容windows).后来发现实现起来特别麻烦, 就想到python.听说这家伙在什么地方都能发挥作用.所以想用python来做通讯模块...所 ...

  4. PHP 多线程、多进程

    多线程:PHP其实并不支持多线程,只是通过一些扩展或者socket方式伪装成多线程,实质不是的.在PHP 5.3 以上版本,使用 pthreads PHP扩展,可以使PHP真正地支持多线程:或者使用 ...

  5. 如何在http请求中使用线程池(干货)

    这段时间对网络爬虫比较感兴趣,实现起来实际上比较简单.无非就是http的web请求,然后对返回的html内容进行内容筛选.本文的重点不在于这里,而在于多线程做http请求.例如我要实现如下场景:我有N ...

  6. Python Socket请求网站获取数据

     Python Socket请求网站获取数据 ---阻塞 I/O     ->收快递,快递如果不到,就干不了其他的活 ---非阻塞I/0 ->收快递,不断的去问,有没有送到,有没有送到,. ...

  7. 使用Charles抓取APP之HTTPS请求

    Charles是一款非常好用的抓包工具,通常使用它来进行APP开发抓包调试,尤其是HTTPS请求. 一.安装Charles 去官网(https://www.charlesproxy.com/)下载软件 ...

  8. Android多线程下载

    所用知识点: 1.设置http协议字段Range “bytes=“start+”-”+end conn.addRequestProperty("Range", "byte ...

  9. http请求及缓存框架 GalHttprequest

    GalHttprequest 是一个android平台上一个轻量级的http网络请求及缓存框架.当前GalHttpRequest支持以下功能: 同步请求Stirng.InputStream.Bitma ...

随机推荐

  1. 操作系统开发系列—13.h.延时操作

    计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ.在每一个时钟周期(CLK cycle),计数器值会减1,当减到0时,就会触发一个输出.由于计数器是16位的,所以最大值是655 ...

  2. 两个Service之间相互监视的实现

    在实际开发中可能需要用到两个Service相互监视的情况,本示例就是实现此功能以作参考. 服务A: public class ServiceA extends Service { private st ...

  3. iOS之 PJSIP蓝牙外设音频支持

    如题,蓝牙设备作为音频输出,在app中如果包含VoIP那么就要设定当连接蓝牙设备时候是否选择或者支持蓝牙输出 最近在处理一个工单就是公司的voip-app与硬件话机底座联调(蓝牙2.0)坑爹的如果是4 ...

  4. vs出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案

    经过本人测试,这种问题一般出现在装了svn的项目. 其实删除了删除sln和csproj文件中的SVN配置信息就行了 需要删除的信息 sln文件中: GlobalSection(SubversionSc ...

  5. DFX 安全测试-- 告诉你什么是XSS、sql注入?POST和GET的区别....

    1.用户权限测试 (1) 用户权限控制 1) 用户权限控制主要是对一些有权限控制的功能进行验证 2) 用户A才能进行的操作,B是否能够进行操作(可通过窜session,将在下面介绍) 3)只能有A条件 ...

  6. sshd安装

    centos yum install openssh-server #chkconfig --level 2345 sshd on #service sshd restart 重新启动 #netsta ...

  7. Nodejs——包与NPM

    在模块之外,包和NPM则是将模块联系起来的一种机制. CommonJS的包规范由包结构和包描述文件组成. 包实际上是一个存档文件,即一个目录直接打包为.zip或tar.gz格式的文件. 完全符合Com ...

  8. .net开发中常用的第三方组件

    .net开发中常用的第三方组件 2013-05-09 09:33:32|  分类: dotnet |举报 |字号 订阅     下载LOFTER 我的照片书  |   RSS.NET.dll RSS. ...

  9. 分享2个网址二维码API接口

    分享2个网址二维码生成API接口,用它们只需要填写好网址就能自动生成二维码,分别来自与bshare和jiathis分享工具中,如您需要就把下面的二维码生成API接口复制到你需要地方. 说明:把url= ...

  10. yii2 rbac权限控制之菜单menu详细教程

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...