Асинхронные вопросы сокетов - PullRequest
1 голос
/ 08 марта 2011

Хорошо, я обнаружил в этом вопросе, что опросные сокеты не масштабируются, поэтому я решил изучить асинхронные сокеты, и у меня есть несколько вопросов.

  1. Если у меня есть несколько сотен клиентов, пытающихся отправить данные своему партнеру, какой наилучший асинхронный метод использовать? select () poll () или я могу просто вызвать recv () для неблокирующего сокета?
  2. Когда я опрашиваю и обнаруживаю, что есть данные для чтения, я должен создать поток, чтобы позаботиться об этом?
  3. Должен ли я беспокоиться о какой-либо функции сна или просто позволить программе использовать 100% ЦП?
  4. Будет ли вообще эффективно поместить всю эту функциональность в класс? Я действительно хотел бы сделать что-то вроде этого:

//thread 1:  
while(!quit){  
   manager.check_clients();  
   manager.handle_clients();  
   manager.display_clients();  
 }
//thread 2:
while(!quit)
  manager.manage_admin_input();

Ответы [ 3 ]

3 голосов
/ 08 марта 2011

Выбор метода опроса зависит от ОС.На 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
}

Независимо от того, хотите ли вы реализовать это в каждом потоке в пуле потоков, или только один раз вОсновной поток, зависит от остальной части вашего приложения.Ключ должен позволить функции опроса подождать, таким образом вы не будете использовать чрезмерную загрузку ЦП.

Вы можете использовать неблокирующие сокеты или ioctl(FIONREAD..., чтобы проверить, сколько данных читается на каждомразъем.

Мой предпочтительный дизайн ООП для обработки сокетов состоит в том, чтобы сделать сокет полностью не осведомленным о обработчике сокетов.Опросник сокетов, скрывающий фактическую функцию, используемую для опроса, будет принимать сокеты и события, которые он должен отслеживать, опрашивать, например, в функции 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 голос
/ 08 марта 2011

Несмотря на то, что на этот вопрос уже дан ответ, вы можете рассмотреть возможность использования Boost.Asio для своей коммуникационной платформы. Он красиво упаковывает различные методы опроса на различных платформах в чистую, согласованную и безопасную для заголовка библиотеку. Он зрелый, хорошо поддерживается и часто обсуждается на SO .

0 голосов
/ 30 мая 2011

Вы можете использовать Push Framework, http://www.pushframework.com Он эффективно использует асинхронные операции ввода-вывода. Также будет абстрагироваться от подробностей низкого уровня, чтобы вы могли сосредоточиться на бизнес-логике вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...