Libevent Programming Troubleshooting

Source: Internet
Author: User
Tags epoll signal handler

http://blog.csdn.net/luotuo44/article/details/39547391

Reprint Please specify Source: http://blog.csdn.net/luotuo44/article/details/39547391

The Event_add function should normally be called in the Libevent callback,

If you want to call Event_add in another thread, it is thread insecure and you can use evthread_use_pthreads

Alternatively, you can refer to the EVTHREAD_NOTIFY_BASE notification main thread for information on how the main thread knows the threads have added an event.

or see Ttnotifyev.

Some time ago read the source code of Libevent. After reading, some of the questions before using libevent have been enlightened. For libevent source analysis, you can http://blog.csdn.net/luotuo44/article/category/2435521 view. If you are a beginner of libevent, you can read the example of libevent use, from simple to complex.

This paper, by self-answer, hopes to help other people to solve some doubts when using libevent.

can a file descriptor be associated with more than one event?

The same file descriptor (FD) can be called event_new multiple times, producing a different event. These event with the same FD, the callback function and the callback parameter can be different. And the events they listen to can also be different (this may be the reason for correlating more than one event).

If multiple events listen to the same event for the same FD, such as a readable event. Then when this fd becomes readable, all of the callback functions that listen for the event are called (that is, trigger event). The callback function for an event that does not listen for the events is not called. If two events listen to different occurrences of the same FD, their triggers are independent of each other.

can a timeout event call the Event_add function multiple times?

A timeout event is a event_add function that can be called multiple times. In fact, all event can call the Event_add function multiple times. However, only a timeout event can be invoked more than once, and other event multiple invocations will be discovered and then repatriated (return).

If the timeout value is different for each call to Event_add, the last call will prevail. If you want to cancel the timeout and make the event a normal event, simply set the second parameter of Event_add to NULL.

How do I set a timeout event to a permanent trigger (ev_persist)?

With the EVTIMER_XXX macro function provided by libevent, it is not possible to set a timeout event to permanent. So some people would like to call the Evtimer_add function again in the timeout callback function of the timeout event. This is a bit like setting the signal handler function again for unreliable signals.

In fact, you do not use these EVTIMER_XX macro functions provided by Libevent. An event is a timeout event, not because the macro functions are called evtimer_xx, but because the second argument is not NULL when the Event_add function is called. So we can set a permanent timeout event like the following code

[CPP]View Plaincopy
    1. struct Event *ev = event_new (base,-1, Ev_persist, CB, ARG);
    2. struct Timeval timout = {2, 0}; //Two-second timeout
    3. Event_add (EV, &timeout);


does the implementation of the timeout event depend on the system time?

You can also ask: Using the timeout event, if the user manually modified the system time, will have an impact?

If your system supports monotonic time, it has no effect. If not supported then there will be some effect, that is, the timeout is not so accurate. For monotonic time, refer to here. You can use the following code to test whether your system supports monotonic time.

[CPP]View Plaincopy
    1. struct TIMESPEC ts;
    2. if (Clock_gettime (clock_monotonic, &ts) = = 0)
    3. printf ("Support \ n");
    4. Else
    5. printf ("not supported \ n");

If it is not frequently modified, if it is modified only once, then only the first time after the modification of the timeout may (only possible) be less accurate, and then the timeout is accurate (if the event has the ev_persist option). Why say "just", "Not so"? Because it depends on the system time you modified in the Libevent state. For details, refer to http://blog.csdn.net/luotuo44/article/details/38661787#t2.

Is it possible to capture a signal and use the signal event for that signal at the same time?

No!!

Because the libevent internal implementation of the signal event principle is to set a signal capture function (This is also known as the Unified Event source). Readers familiar with the signal capture should understand that the signal capture function can only have one. You set the other one, then the previous settings will be overwritten.

in Linux, does libevent use Epoll by default?

If your system supports Epoll, it will use Epoll first. In fact, Libevent always chooses the high-performance multi-io multiplexing function (an exception on Windows, which does not take precedence over IOCP).

How do you know libevent specifically which multi-channel IO multiplexing function is used?

When you call Event_base_new to get a event_base, make sure which multiplexing function is used. Call the Event_base_get_method function at this point to get the event_base using which multi-io multiplexing function. The function returns a string in which the contents of the string are the names of the multiple IO multiplexing functions "select", "Poll", and "Epoll". On the Windows platform, however, the "Win32" is returned. In general, select is selected on the Windows platform. As for when to choose the IOCP, you can refer to the next article.

in Windows, how do I use IOCP?

In Windows, libevent support for IOCP is relatively small. IOCP is supported only in connection listeners Evconnlistener and bufferevent sockets. Also, because libevent selects select by default on the Windows platform, Libevent uses IOCP by setting the EVENT_BASE_FLAG_STARTUP_IOCP macro.

You can set this macro by using the Event_config_set_flag function. Specific content can refer to the settings, you can refer to Http://blog.csdn.net/luotuo44/article/details/38443569#t5

when do I call the Evthread_use_pthreads function?

If you want to use multi-threading and require thread safety, be sure to call the function before calling the Event_base_new function (the corresponding version of Windows is Evthread_use_windows_threads). If you call evthread_use_pthreads after Event_base_new, the event_base will not be thread-safe. The principle can be referred to here http://blog.csdn.net/luotuo44/article/details/38501341#t0.

Note: This function is just to make sure that libevent thread is safe, multithreading is used to write code on its own. The code inside the libevent is not multi-threaded, it only uses locks and condition variables.

Libevent allows custom memory allocations, logs, and thread locks, which are ordered in order?

Yes. First, the customizations to these three items should be placed in front of the program, ensuring that they are placed before any other Libevent API calls. Second, the three are also in order. They should be in the following order: memory allocation, logging, and thread lock.

can I add an event on the secondary thread call Event_add?

OK. But for security, you must make sure that your program calls the Evthread_use_pthreads function at the beginning. If the main thread is not invoking a callback function for another event, then the event is immediately added to the listener queue by the main thread, waiting for events to occur with the other event. As for how the main thread knows the threads have added an event, refer to the EVTHREAD_NOTIFY_BASE notification main thread.

libevent which functions are thread-safe?

You think a function is supposed to be thread-safe, and the author of Libevent will assume that the function is thread-safe.

Once you have called the Evthread_use_pthreads function, be assured of using the functions provided by Libevent. It always locks when the need to lock, to ensure that the thread-safe.

bufferevent thread safe?

You added the Bev_opt_threadsafe option when you called Bufferevent_socket_new, so it's thread-safe.

bufferevent_write non-blocking?

Non-blocking. After the call, it is not blocked and can be returned immediately.

since Bufferevent_write returns immediately, can the user's copy of the data be deleted after the return?

If a reader tries to write a non-blocking socket's sending code just by using the System network API provided by the OS, it must be dead-blocked. You have to consider that the data you are sending is not finished in one write call. At this point, you have to find a place to save the data you want to send, and then use it the next time you call write. But finding a place is an annoying thing.

Although Bufferevent_write is non-blocking, but it is very good. When it returns, he has copied a copy of the data that the user wants to send, saved in the internal buffer. So when you return from Bufferevent_write, you can discard the data you want to send, without having to find a place to save the data.

is the bufferevent readable event a horizontal or an edge trigger?

Bufferevent-readable events are edge-triggered. That is, if the client sends 100 bytes of data to the server, and the client is only sending the data once. After the server triggers a readable event, the 100 bytes should be read out (assuming that the 100 bytes arrived together). It should not be thought that this callback reads only 4 bytes (such as length information) and then waits until the next callback to read the other data. Because the client sends only one data at a time, there is no next callback, even if there is data in the bufferevent buffer.

Of course, if the client sends the data again, then the bufferevent's readable callback function is called.

The specific principle can refer to http://blog.csdn.net/luotuo44/article/details/39344743#t6.

what does the high water level of the bufferevent read event mean?

The low water level of the read event is easier to understand, and the user-set readable callback function is called when the data of the bufferevent read buffer reaches the low water level. For example, the user sets a low water level of 4 bytes, because the user thinks that less than 4 bytes is not worth processing. The user's readable callback function is not called when the amount of data in the bufferevent read buffer is less than 4 bytes. When the amount of data is greater than or equal to 4 bytes, the user's readable callback function is called.

What is the high water level of the reading event? By default (that is, no high water level is set), once the socket FD has data readable, the libevent will read the data from the kernel buffer of the socket FD to the bufferevent read buffer. The client sends a large amount of data to the server, and the server constantly copy the data into the bufferevent buffer. In this case, the TCP Sliding window protocol is useless.

The high water level of the read event arises at this time, when the data volume of the bufferevent read buffer reaches this high water level, the data is no longer read from the socket FD. At this point, the kernel buffers of the socket FD accumulate large amounts of data, and the sliding window protocol works. When the number of read buffers for bufferevent is less than the high water level, libevent can then read the data from the buffer of the socket FD. Stop read, resume read this sequence of operations is done by Libevent, who is completely unaware. Some readers may think: Now that you've listened to a readable event, how do you do it? The socket kernel buffer preserves both data and avoids the endless triggering of readable events. Libevent's solution can refer to HTTP://BLOG.CSDN.NET/LUOTUO44/ARTICLE/DETAILS/39344743#T5.

the second thread calls Bufferevent_write, why can't I send the data?

In this case, it is generally the main thread running in Event_base_dispatch. The user wants to call Bufferevent_write in the secondary thread to send the data.

First, make sure you have called the Evthread_use_pthreads function (the Windows platform is the Evthread_use_windows_threads function).

Second, make sure you're calling before the Event_base_new function.

Why can I read up to 4096 bytes at a time when using bufferevent?

If the client sends a large amount of data to the server, and the server is using Bufferevent. In Bufferevent's Read event callback function, it is generally possible to receive a maximum of 4,096 bytes. This is libevent the library itself is limited by the code.

Libevent The supervisor hears a socket FD readable, it will go to the data from the socket FD kernel buffer data copy into a buffer inside the bufferevent. However, libevent only copy up to 4096 bytes at a time, even if there is more data in the buffer of the socket FD. The user reads the data in the Read event callback function, which is read from the buffer inside the bufferevent. So you can read up to 4096 bytes. Of course, if the user intentionally did not read this 4096 bytes, then the next can read more than 4096 bytes.

For some scenarios, only copy 4096 bytes, performance is not enough. At this point, you can only modify the source code of the libevent and recompile. At the back of the link you can see why libevent only reads 4096 bytes from the socket FD at a time, where it can be modified. Http://blog.csdn.net/luotuo44/article/details/39325447#t11

What is the difference between compiling the four static libraries generated by Libevent in Linux?

In Linux, compiling libevent will produce the following static library Libevent.a, Libevent_core.a, LIBEVENT_EXTRA.A, LIBEVENT_PTHREADS.A

The differences between the four static libraries are:

      • EVENT_CORE.A: Contains the core content of Libevent. such as event, buffer, bufferevent, log, Epoll, Evthread
      • EVENT_EXTRA.A: Contains the four additional features that Libevent provides: event_tagging, HTTP, DNS, RPC
      • EVENT_PTHREADS.A: Contains the specific implementation of the pthreads thread
      • EVENT.A:EVENT.A = Event_core + Event_extra

Libevent Programming Troubleshooting

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.