5 ms·
Use libuv instead of writing this stuff yourself.
by johnm 15y ago
Use libuv instead of writing this stuff yourself.
- jrockway 15y agoIt's essential to understand how an event loop works before you use one from a library. If you don't "get it", you won't write an application that uses it effectively. Don't write your own event loop for production code; write it to learn how they work. (Also: uv? Really? That's a pretty bloated library that does everything from handling timers to figuring out the 15-minute load average on OpenBSD. If you just want timers and fds, use something simpler. select is actually fine for a large majority of applications.)
- tptacek 15y agoI wouldn't use select() directly in any application that needed timers. Libevent and libev are fine solutions to this problem. And I don't think you need to learn how to use epoll or kqueue to make use of them.
- jrockway 15y agoThere is some bookkeeping involved when you want IO watchers and timers, but it amounts to a heap for the timers ("when does the next timer go off?"), calling select with the timeout set for when the next timer expires, and then updating the timer queue when you wake up (if it's because the timer time arrived, rather than because IO is possible). That's basically why we have event loop libraries, to tie those two data structures together. The critical thing to learn about epoll is event-triggering and level-triggering. I've seen people write libev code where they make watchers for r and w on a socket, then keep those alive regardless of whether or not they have data to write. This means their process never goes to sleep, since the fd is always writable and the write callback is called every time the process tries to go to sleep. They are expecting edge-triggering when ev provides level-triggering. On the other hand, I've seen people using libzmq with libev have the opposite problem. libev's watchers are level-triggered, but libzmq's ZMQ_FDs are edge-triggered. This means you really have to know what you're doing to get things to work (but if you treat the ZMQ_FD like you should treat a normal fd, that is, read until EWOULDBLOCK and write until EWOULDBLOCK, it works), and reading an article that discusses how both work could be helpful in getting you to write correct code. OTOH, the terms themselves are pretty clear.
- tptacek 15y agoFrom what I can tell, less than half of all "evented" C code gets write events correct. The error far more common than busypolling the write event is not having write events at all, and just assuming that socket writes never block. But I'm just saying that timers actually take a little bit of data structure work to get right; when it takes chin-ups just to get basic timers, code tends to have crappy (inefficient, slow) timing. Any good event library should give you the ability to schedule thousands and thousands of fine-grained timers without worrying about storage or the amount of time it takes to find the next wait interval.
- justincormack 15y agoOr you use timerfd(2) and get the kernel to manage the timer heap. Under Linux anyway.
- jrockway 15y agoNice. What's next; the kernel getting its own version of printf?
- vilya 15y agoYou mean kprintf? http://leaf.dragonflybsd.org/cgi/web-man?command=kprintf§ion=9 http://leaf.dragonflybsd.org/cgi/web-man?command=kprintf&...
- tptacek 15y agoI think you're deliberately misconstruing 'jrockway's point. The kernel has an internal printf, but userland programs don't ask the kernel to printf-format strings for them.
- deleted 15y ago[deleted]
- deleted 15y ago[deleted]
- X-Istence 15y agoDid you mean libev?
- taf2 15y agonah, he means libuv - because that's the layer on top of libev and libeio used by node.js to also include win32 support...
- uriel 15y agoEvents are evil, much better use something like Plan 9 (port) libthread ( http://man.cat-v.org/plan_9/2/thread http://man.cat-v.org/plan_9/2/thread ) or Russ Cox's libtask ( http://swtch.com/libtask/ http://swtch.com/libtask/ ). Or better yet, program in Go ;)
- tptacek 15y agoMost network programs spend much of their entire life waiting for IO events. I have no argument in principle for the idea that you should restructure your whole program's control flow with transparent cooperative scheduling to attempt to get the best of both worlds of straight-line coding and efficient scheduling, except that it feels to me like you're kind of not really even writing C code anymore at that point. This might be irrational of me. In the meantime, if you're not going to adopt an exotic thread scheduling library, I think events are the way to go. POSIX threads don't make much sense to me.
- p9idf 15y ago"I have no argument in principle for the idea that you should restructure your whole program's control flow with transparent cooperative scheduling" Maintaining any kind of long-term state for the functions which the event loop calls can be trickier than it needs to be, since they need to quickly return and can't leave anything on their stack.
- SamReidHughes 15y agoDevelopment using coroutine libraries goes much faster and the resulting code is much more robust than that which uses events and callbacks. This is even more strongly the case in C++ where you can take advantage of traditional C++ RAII on any coroutine stack, which you couldn't do so nicely and clearly with callbacks. In the ten months since we started using them, we've had no stability problems and no strange and inscrutable bugs from within our coroutine implementation. There have been user errors from misuse of coroutines, but nothing anywhere near the order of magnitude of what you get when using callbacks.
- Peaker 15y ago
- MostAwesomeDude 15y agoUse Twisted instead of inventing libuv. >:3
- burgerbrain 15y agoThat is unfortunately only an option if you are developing in Python.
- MostAwesomeDude 15y agolibuv's realistically only an option if you're in Node. I know of no libevent/libev consumers at the C level who are going to switch to libuv as soon as it becomes more stable.