面试题答案
一键面试Windows 平台
- 优化措施:使用
WSAAsyncSelect
或WSAEventSelect
替代select
。 - 原理:
select
在 Windows 下性能受限于 FD_SETSIZE 大小,并且每次调用都要复制大量数据到内核。WSAAsyncSelect
基于消息机制,应用程序通过窗口消息接收网络事件通知,避免了每次轮询的开销。WSAEventSelect
使用事件对象,应用程序可以通过等待事件对象的状态变化得知网络事件,减少了不必要的轮询。 - 实现思路:
- WSAAsyncSelect:通过
WSAAsyncSelect(socket, hWnd, wMsg, lEvent)
函数,将网络事件(如 FD_READ、FD_WRITE 等)与窗口消息关联,当事件发生时,系统会向指定窗口发送消息,应用程序在窗口消息处理函数中处理网络事件。 - WSAEventSelect:使用
WSAEventSelect(socket, hEventObject, lNetworkEvents)
函数,将网络事件与事件对象关联,应用程序通过WaitForMultipleObjects
等函数等待事件对象触发,从而处理网络事件。
- WSAAsyncSelect:通过
Linux 平台
- 优化措施:使用
epoll
替代select
。 - 原理:
select
在 Linux 下存在一些性能瓶颈,如每次调用需要将文件描述符集合从用户空间复制到内核空间,并且内核需要线性遍历整个文件描述符集合来检查事件。epoll
采用事件驱动机制,通过epoll_create
创建一个 epoll 实例,epoll_ctl
向该实例中添加、修改或删除要监控的文件描述符,epoll_wait
等待事件发生。epoll
使用红黑树来管理要监控的文件描述符,用链表来存储就绪的事件,大大提高了查找和遍历效率。 - 实现思路:
- 首先调用
epoll_create
创建一个 epoll 实例,得到一个 epoll 句柄。 - 然后通过
epoll_ctl
函数将需要监控的文件描述符添加到 epoll 实例中,并指定要监控的事件(如 EPOLLIN、EPOLLOUT 等)。 - 最后在主循环中调用
epoll_wait
等待事件发生,当有事件发生时,epoll_wait
返回就绪的事件列表,应用程序遍历该列表处理相应事件。
- 首先调用