1.I/O线程,这种线程的主循环是多路复用,阻塞地等待在select/poll/epoll_wait系统调用上。这类线程也可以处理定时事件,例如利用timerfd,加入到poll/epoll_wait中进行监听,实现定时功能。当然它的功能不止IO,有些简单计算也可以放在其中,比如消息的编码或者解码。
2.计算线程(习惯叫事件线程),这类线程的主循环是阻塞的事件队列,阻塞地等在条件变量上,这样的线程可以有多个位于线程池中,这种线程通常不涉及I/O,一般要避免任何阻塞操作(尽量不要有系统调用函数,如read write之类的函数)。当然根据实际情况也可以试非阻塞的事件循环,不断轮询从事件队列中取得事件执行,在我们平时的游戏服务器端中,一般从事件队列里处理完事件后,会根据执行事件进行极短时间(毫秒级的)的sleep,这样做是因为用来计算的事件线程要处理一些timetick,所以不能一直阻塞直到有新的事件道来,至于为什么做,是防止如果事件不来进入busy-wait状态,sleep是系统函数,调用会陷入内核态让出CPU。
3.第三方库所用的线程,比如日志线程,再比如数据库线程。无论日志线程还是数据库线程一般涉及写硬盘的操作,比较慢,如果放到事件线程中,会造成CPU闲置。