Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use libevent and pthread together in C

Tags:

c

libevent

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?

like image 390
Bruce Dou Avatar asked Jun 20 '12 10:06

Bruce Dou


2 Answers

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.

like image 144
aditya Avatar answered Oct 21 '22 00:10

aditya


That would work.

In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.

To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread wakes up and read the pointer from the pipe.

like image 32
Maxim Egorushkin Avatar answered Oct 21 '22 01:10

Maxim Egorushkin