Our de facto method for asynchronous programming at Meebo is to use a single thread with non-blocking sockets and some sort of socket watching/readiness notification (poll, select, epoll, libevent, glib’s mainloop, etc). This is what Pidgin does, too. It is by far my favorite approach to asynchronous programming. (There are some other approaches listed in Dan Kegel’s article The C10K problem.)
It works especially well for clients. For servers, if you want to take advantage of multiple processors or multiple cores then you either have to spawn threads or use multiple processes.
We use MySQL a lot at work. And we use C a lot. Unfortunately the C API for MySQL is synchronous. This means if you perform a query then the entire application sits idle until the database server responds. This is extremely inconvenient. There are various hacks and 3rd party libraries you can use to perform asynchronous queries, but they’re a bit ugly and don’t work that well. We ended up writing a proxy server that runs on the local machine and proxies queries to the database. So the client connects to the proxy and submits a query, control is returned to the client immediately, the client’s event loop watches the socket connected to the proxy server and calls a callback function once the proxy has returned the result from the database.
It works well enough, but I feel like the world would benefit from a solid asynchronous MySQL C API. Or maybe we should just switch to PostgreSQL.
P.S. epoll is ridiculously sweet. If you’re concerned about the performance of a network-heavy application then use epoll (or kqueue if you’re on BSD)! The difference is night and day.