select and poll select(2) and poll(2) allow waiting for events You state what set of descriptors you are interested in The caller is reported what descriptors are active You can set a timeout Normally, main() is a loop based on select(2) A process must sleep as much as possible Asynchronous events are notified immediately Timeouts have the same granularity as the system clock Since everything is a file, most situations can be attacked with a main loop based on select(2) or poll(2) This predates multi-threading It may be way more efficient than multi-threading Unless you really need concurrency on a multi-core system