利用libevent 和线程池实现高并发服务器的设计

主进程添加监听套接字的事件并进行事件循环,将连接描述符放入定义的数据结构中,并在主进程中进行写管道,触发子线程的读管道事件,然后从连接结构中获取连接描述符进行和客户端进行通信。其中主进程和子线程都有不同的基事件base.

 

 

#include 
#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 

#include 

#include 

const int thread_num = 10;
#define BUF_SIZE 1024

using namespace std;

typedef struct {
    pthread_t tid;
    struct event_base *base;
    struct event event;
    int read_fd;
    int write_fd;
    //queue q;
    int f_connect;
    char * buffer;
}LIBEVENT_THREAD;                 //需要保存的信息结构,用于管道通信和基事件的管理

typedef struct {
    pthread_t tid;
    struct event_base *base;
}DISPATCHER_THREAD;

LIBEVENT_THREAD *threads = (LIBEVENT_THREAD *) calloc(thread_num, sizeof(LIBEVENT_THREAD));

void on_write(int sock, short event, void* arg);

void on_read(int sock, short event, void* arg)
{

    cout<<"on_read() called, sock="<q.pop();
       close(sock);
        return;
    }
    cout<<"i have receive: "<buffer=buffer;

    struct event* write_ev = (struct event*)malloc(sizeof(struct event));//发生写事件(也就是只要socket缓冲区可写)时,就将反馈数据通过socket写回客户端
    event_set(write_ev, sock, EV_WRITE, on_write, event_thread);

    event_base_set(event_thread->base, write_ev);
    event_add(write_ev, NULL);
    cout<<"on_read() finished, sock="<buffer,sizeof(event_write_thread->buffer));
    //--本来应该用while一直循环,但由于用了libevent,只在可以读的时候才触发on_read(),故不必用while了
    write(sock, event_write_thread->buffer, BUF_SIZE);

    free(event_write_thread->buffer);

    event_write_thread->buffer=NULL;

}

static void thread_libevent_process(int fd, short which, void *arg)
{
    int ret;
    char buf[128];
    LIBEVENT_THREAD *me = (LIBEVENT_THREAD *) arg;

    int fdconnect;

    if (fd != me->read_fd) {
        printf("thread_libevent_process error : fd != me->read_fd\n");
        exit(1);
    }

            ret = read(fd, buf, 128);
           if (ret > 0) 
            {

              buf[ret] = '\0';

              printf("thread %llu receive message : %s\n", (unsigned long long)me->tid, buf);

            }

           cout<<"thread_libevent_process\n"<q.size()>0)
        {
            fdconnect=me->q.front();
            me->q.pop();

           ret = read(fd, buf, 128);
           if (ret > 0) 
            {

              buf[ret] = '\0';

              printf("thread %llu receive message : %s\n", (unsigned long long)me->tid, buf);

            }
        }*/

        /*if(me->q.size()>0)
        {
            fdconnect=me->q.front();

            cout<<"thread_libevent_process succeed "<q.pop();
        }

        else
            return ;*/

        fdconnect=me->f_connect;

        struct event* read_ev = (struct event*)malloc(sizeof(struct event));//发生读事件后,从socket中取出数据

        event_set(read_ev, fdconnect, EV_READ|EV_PERSIST, on_read, me);

        event_base_set(me->base, read_ev);

        event_add(read_ev, NULL);

    return;
}

void thread_init()
{
    int ret;
    int fd[2];
    for (int i = 0; i < thread_num; i++) {

            ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, fd);

            if (ret == -1) {
                perror("socketpair()");
                return  ;
            }

            threads[i].read_fd = fd[0];
            threads[i].write_fd = fd[1];

            threads[i].base = event_init();

            if (threads[i].base == NULL) {
                perror("event_init()");
                return ;
            }

            event_set(&threads[i].event,threads[i].read_fd, EV_READ | EV_PERSIST, thread_libevent_process, &threads[i]);

            event_base_set(threads[i].base, &threads[i].event);
            if (event_add(&threads[i].event, 0) == -1) {
                perror("event_add()");
                return ;
            }

            cout<<"thread_init succeed"<tid = pthread_self();

    //event_base_loop(me->base, 0);

     event_base_dispatch(me->base);//每个工作线程都在检测event链表是否有事件发生

    return NULL;
}

void CreatPhreadPool()
{

    for (int i = 0; i < thread_num; i++) {
        pthread_create(&threads[i].tid, NULL, worker_thread, &threads[i]);
    }

    cout<<"CreatPhreadPool"<f_connect=new_fd;

    write(thread->write_fd, " ", 1);

    cout<<"on_accept() finished for fd="<

 

 

 

 

[code]![这是设计服务器的框图]

!(http://static.oschina.net/uploads/img/201409/10221620_WNjs.jpg)

!(http://static.oschina.net/uploads/img/201409/10221623_IRcr.jpg)

 

 

你可能感兴趣的:(libevent)