How to use libevent and pthread together in C

Bruce Dou picture Bruce Dou · Jun 20, 2012 · Viewed 9.2k times · Source

The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?

Answer

aditya picture aditya · Dec 21, 2017

Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.

Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :

#include <stdint.h>
#include <pthread.h>
#include <event.h>

void * thread_func (void *);

int main(void)
{
    int32_t tid = 0, ret = -1;
    struct event_base *evbase;
    struct event *timer;
    int32_t *t_ret = &ret;
    struct timeval tv;

    // 1. initialize libevent for pthreads
    evthread_use_pthreads();

    ret = pthread_create(&tid, NULL, thread_func, NULL);
    // check ret for error

    // 2. allocate event base
    evbase = event_base_new();
    // 3. allocate event object
    timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
    // 4. add event
    tv.tv_sec = 0;
    tv.tv_usec = 1000;
    evtimer_add(timer, &tv);
    // 5. start the event loop
    event_base_dispatch(evbase);   // event loop

    // join pthread...

    // 6. free resources
    event_free(timer);
    event_base_free(evbase);
    return 0;
}

void * thread_func(void *arg)
{
    struct event *ev;
    struct event_base *base;

    base = event_base_new();
    ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
    event_add(ev, NULL);  // wait forever
    event_base_dispatch(base);  // start event loop

    event_free(ev);
    event_base_free(base);
    pthread_exit(0);
}

As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :

  1. call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
  2. Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
  3. Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
  4. Schedule the event for execution
  5. Start the event loop
  6. free the resources when done.

Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.

cheers.