自己写了一个测试例子:
/* *********************************************************
* Copyright 2014 ***
* Author : zhongcy
* Email : zzhongcy@gmail.com
********************************************************* */
#include <stdio.h>
#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_atomic.h"
#include "apr_thread_proc.h"
#include "event2/thread.h"
#include "event2/event.h"
#include "event2/bufferevent.h"
apr_pool_t *test_global_pool = NULL;
apr_pool_t *busi_pool = NULL;
apr_pool_t *msg_pool = NULL;
struct event_base *io_base = NULL;
apr_thread_t *io_thread = NULL;
struct bufferevent *io_bufferevent = NULL;
struct event_base *zcy_event_base_new(void)
{
#if WIN32
return event_base_new();
#else
struct event_base *base = NULL;
struct event_config *cfg = event_config_new();
if (cfg) {
event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
base = event_base_new_with_config(cfg);
event_config_free(cfg);
}
return base;
#endif
}
void * zcy_base_new (void) {
#ifdef WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
/* IO Base */
io_base = zcy_event_base_new();
return NULL;
}
void zcy_base_destroy (void) {
bufferevent_free(io_bufferevent);
event_base_free(io_base);
}
static void *APR_THREAD_FUNC zcy_work_rounte(apr_thread_t *thread, void *arg) {
struct event_base *base = NULL;
base = (struct event_base *)arg;
evthread_make_base_notifiable(base);
event_base_loop(base, EVLOOP_NO_EXIT_ON_EMPTY);
return NULL;
}
int zcy_thread_start() {
int i = 0;
apr_threadattr_t *attr = NULL;
apr_status_t rv = 0;
apr_threadattr_create(&attr, busi_pool);
/* IO thread */
rv = apr_thread_create(&io_thread, attr, zcy_work_rounte, io_base, busi_pool);
if(APR_SUCCESS != rv) {
return rv;
}
return 0;
}
int zcy_thread_stop (void) {
apr_status_t rv = 0;
event_base_loopbreak(io_base);
apr_thread_join(&rv, io_thread);
return 0;
}
static void write_cb(struct bufferevent *bufev, void *arg) {
static int write_num = 0;
write_num++;
printf("write_cb :%d\n", write_num );
}
static void read_cb(struct bufferevent *bufev, void *arg) {
static int read_num = 0;
read_num++;
printf("read_cb :%d\n", read_num);
}
int zcy_connection_init (char *host, int port) {
int rv = 0;
struct sockaddr_in sin;
io_bufferevent = bufferevent_socket_new(io_base, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
if(io_bufferevent == NULL) {
rv = -1;
goto conn_init_error;
}
rv = bufferevent_enable(io_bufferevent, EV_READ | EV_WRITE);
if(0 != rv) {
goto conn_init_error;
}
/* cb */
bufferevent_setcb(io_bufferevent, read_cb, write_cb, NULL, socket);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(host);
sin.sin_port = htons(port);
rv = bufferevent_socket_connect(io_bufferevent, (struct sockaddr *)&sin, sizeof(sin));
if(0 != rv) {
printf("connect failed![%d]", rv);
}
conn_init_error:
return rv;
}
/* Send a message to the socket */
int zcy_msg_send (void *data, int len) {
struct evbuffer *obuf = bufferevent_get_output(io_bufferevent);
evbuffer_add_reference(obuf, data, len, NULL, NULL);
//evbuffer_add(obuf, data, len);
return 0;
}
#define MSG_LEN 512
int main(int argc, char* argv[])
{
int rv = 0, i = 0, j = 0;
char *msg_bug = 0;
char buf[32] = {0};
int sleep_num = 0;
apr_allocator_t *allocator = NULL;
apr_thread_mutex_t *alloc_mutex = NULL;
/* APR */
rv = apr_initialize();
if(rv != APR_SUCCESS)
return rv;
apr_pool_create(&test_global_pool, NULL);
apr_pool_create(&busi_pool, test_global_pool);
apr_allocator_create(&allocator);
apr_allocator_max_free_set(allocator, 1024*64);
rv = apr_thread_mutex_create(&alloc_mutex, APR_THREAD_MUTEX_DEFAULT, test_global_pool);
if(APR_SUCCESS != rv) {
printf("Failed to create mutex! status[%d]", rv);
return rv;
}
apr_allocator_mutex_set(allocator, alloc_mutex);
apr_pool_create_ex(&msg_pool, test_global_pool, NULL, allocator);
apr_allocator_owner_set(allocator, test_global_pool);
apr_pool_tag(msg_pool, "msg_pool");
zcy_base_new();
zcy_thread_start();
zcy_connection_init("10.10.20.16", 8080);
for(i = 1; i<=10000; i++){
for(j=1; j<100; j++){
msg_bug = apr_pcalloc(msg_pool, MSG_LEN);
memset(msg_bug, 'a', MSG_LEN);
sprintf(buf, "\n\n# %d #\n", 100*i+j);
memcpy(msg_bug, buf, strlen(buf));
zcy_msg_send(msg_bug, MSG_LEN);
apr_sleep(apr_time_from_msec(20));
}
apr_pool_clear(msg_pool);
apr_sleep(apr_time_from_msec(1000));
}
apr_sleep(apr_time_from_msec(1000));
zcy_base_destroy();
zcy_thread_stop();
apr_thread_mutex_destroy(alloc_mutex);
apr_pool_destroy(msg_pool);
apr_pool_destroy(busi_pool);
apr_pool_destroy(test_global_pool);
apr_terminate();
getchar();
return 0;
}