[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: Re: [Libevent-users] std::threads

Hi Azat,
You still have one event_base per thread: https://github.com/ellzey/libevhtp/blob/develop/evthr.c#L107 , which is similar with what I do: https://github.com/Michael-Tieying-Zhang/peloton/blob/master/src/backend/networking/tcp_connection.cpp#L36
>So to summarize you want to move all events handling into separate
>base=thread, and send data to it (how? using pipes?),
What I want to do is :
1. a main thread listening on a even_base, let's call it BASE,
2. when a new connection (conn-1) coming, the listening callback is involked, and a  bufferevent (event-1) is created.  Then the bufferevent (event-1) is put into the BASE with read/write callback functions.
3. when a second connection (conn-2) comming, the listening callback is also involked, and another bufferevent (event-2) is created. Then event-2 is also put into the BASE with event-2's read/write callback functions.
4. When conn-1 recvs some data, event-1's read callback is involked by BASE(main thread). Then, event-1's read callback function reads the message and put it into a message queue, and then returns.
5. There is a thread-pool processing the message queue, so diffenent messages are parallel processed. For example, thread-1 picks up a message from the message queue, process it and put the response message into the socket buffer using (eventbuffer_add()).
So even though some requests might take a long time to process, but other other requests don't block. Because we have different threads to process the message queue.
According to the above model, the event_base and bufferevent should be both thread-safe, because
1. For bufferevent , different threads can add data with the same bufferevent
2. For event_base, different bufferevents in the same event_base might be free and added by different threads.

Date: 2016-03-15 18:08
Subject: Re: RE: [Libevent-users] std::threads
> Thanks Tom. "event bases + threads (each thread running an event base)", that is what I have done. Each connection is a thread with a event_base + a socket_bufferevent. But when a connection has no communication during sometime, the associated thread is idle. That's the main problem I concern.
Hi Michael,
According to what you wrote before this is not 100% correct:
- you have *one event_base*, *multiple threads*
- while Tom suggesting *event_base per thread*
But this is not important though.
> For example, there are 10 connections with the server, and 10 threads on the server are responsible for the connections, e.g., thread-1 is associated with connection-1, with event_base-1 and socket_bufferevent-1. If the client with the connection-1 stop sending messages to the server, the thread-1 is stuck. Becuase thread-1 is running dispatch(event_base-1), which is a blocking API.
dispatch() is a loop that have events for monitoring (see
epoll_wait() and other multiplexing waiters).
> So, I want to put all of the socket_bufferevents in one event_base, and only one thread is runing the event_base. When one of the socket_bufferevents can read or write, the associated callback will pass the read/write data to a thread to process. I suppose this model is more reasonable, right?
So to summarize you want to move all events handling into separate
base=thread, and send data to it (how? using pipes?), if so the answer
is it depends from what data you have it is very reasonable if you
callbacks are simple (IOW fast) that you can use this, otherwise it will
be better to have a thread pool I think (but also it depends on many
things, since you can defer some work into other threads and use main
only for event loop).
> The question is how can I implement that with std::thread. Because our project use std::thread. I see libevent can use pthread (even though there is no example in the documentation) but I am don't know how to use it with std::thread. The explaination is so simple I do not know how to implement it with std::thread.
All you need to do is move something like this into std::thread:
  event_base_loop(base, 0);
And you can use pipes/socketpair to communicate with clients
Anyway here are examples of what I'm talking about:
- https://github.com/azat/boostcache/blob/libevent-aio/src/kernel/net/commandserver.cpp (cpp)
- https://github.com/ellzey/libevhtp/blob/develop/evthr.c (c)
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.