好吧,我在this问题中发现轮询套接字无法扩展,所以我决定调查异步套接字,我有几个问题。
//thread 1:
while(!quit){
manager.check_clients();
manager.handle_clients();
manager.display_clients();
}
//thread 2:
while(!quit)
manager.manage_admin_input();
答案 0 :(得分:3)
轮询方法的选择取决于操作系统。在linux上,使用epoll,最好是边缘触发的。在FreeBSD上,使用kqueue。在Windows上,使用例如WSAEventSelect和WSAWaitForMultipleEvents。
您的主循环应该只是:
for (;;) {
epoll(); // blocking poll until an event happens, optionally with a timeout
// iterate signaled sockets and process data
// Other tasks
}
您是选择在线程池中的每个线程中实现此功能,还是仅在主线程中执行一次,这取决于应用程序的其余部分。关键是让轮询功能进行等待,这样就不会使用过多的CPU。
您可以使用非阻塞套接字或ioctl(FIONREAD...
来检查每个套接字上可读的数据量。
我首选的套接字处理OOP设计是让套接字完全不知道套接字轮询器。套接字轮询器,隐藏用于轮询的实际函数,将接受套接字和它应该监视的事件,在例如轮询中进行轮询。一个tick()
函数,然后告诉每个套接字或一个外部监听类,它有与套接字有关的东西。类似的东西:
class SocketPoller {
public:
void registerSocket(Socket * s, int EventMask);
void unregisterSocket(Socket * s);
virtual void tick() = 0;
}
class SocketPollerEPoll : public SocketPoller {
public:
void tick() {
epoll(...);
// for each socket with events:
TheSocket->notifyReadable();
}
};
class SocketPollerSelect : public SocketPoller {
public:
void tick() {
select(...);
// for each socket with events:
TheSocket->notifyReadable();
}
};
答案 1 :(得分:1)
即使已经回答了这个问题,您也可以考虑将Boost.Asio用于您的通信框架。它很好地将各种平台上的各种轮询方法包装成一个干净,一致且类型安全的头文件库。它是成熟的,得到很好的支持,经常discussed on SO。
答案 2 :(得分:0)
您可以使用Push框架http://www.pushframework.com它有效地使用异步IO。还会抽象出低级细节,以便您可以专注于应用程序的业务逻辑。