Базовый дизайн многопоточного игрового сервера? - PullRequest
0 голосов
/ 01 октября 2010

Как пишутся многопоточные игровые серверы?

Если имеется 4 потока, существует ли один поток, выполняющий игровой цикл, и 3, принимающие и обрабатывающие запросы? Также: отправляется ли информация из потока, запускающего игровой цикл?

Ответы [ 2 ]

0 голосов
/ 02 октября 2010

Главный ключ - убедиться, что ваша игровая логика не зависит от вашей модели потоков.

Таким образом, большинство игровых серверов выглядят примерно так:

main() {

  gGlobalReadOnlyStuff = LoadReadOnlyStuff();

  SpawnThreads(numCores); // could be another limiting resource...
  WaitForThreadsToBeReadyToGo();

  while(1) {
     WaitForNetworkInput(networkInput);

     switch(networkInput.msg) {

     case ADMIN_THING:  // start/stop websever, dump logs, whatever...
          DoAdminThing(networkInput.params);  
          break;

     case SPAWN_GAME: // replace 'game' with 'zone' or 'instance' as needed
          idThread = ChooseBestThread(); // round robin, random, etc
          PostStartGameMessageToThread(idThread, networkInput.msg);
          break;

     // ...

     }
  }

}

void ThreadUpdate() {

   threadLocalStuff = LoadThreadLocalStuff();

   SignalThreadIsReadyToGo();   

   while(1) {

   lock(myThreadsMessageQueue);
   // copy messages to keep lock short
   localMessageQueue = threadsMessageQueue;
   unlock(myThreadsMessageQueue);

   foreach(message in localMessageQueue) {
       switch(message.msg) {
       case SPAWN_GAME:
           threadLocalStuff.games.MakeNewGame(message.params));
           break;
       case ADMIN_THING__LET_EVERYONE_KNOW_ABOUT_SERVER_RESET:
           ...;
           break;
       // etc...
       }
   }


   foreach(game in threadLocalStuff.games) {
       game.Update(); // game will handle its own network communication
   }
}

Два жесткихтогда вещи «приходят с разделом (игра, зона, экземпляр, что угодно), подходящим для вашей игры» и «переносят вещи (игроки, шаровые молнии, эпический лутц) через эти границы» Один типичный ответ - «сериализовать его через базу данных», но вы можете использовать сокеты / сообщения / файлы / что угодно.Но да, где и как сделать эти разделы и свести к минимуму то, что может выйти за границы, тесно связано с вашим игровым дизайном.

(И да, в зависимости от ваших настроек, возможно, есть несколько «общих» систем(ведение журнала, память), для которого может потребоваться многопоточная обработка (или даже лучше, просто иметь один регистратор / кучу на поток))

0 голосов
/ 01 октября 2010

Starkey уже указывал, что все зависит от точного дизайна.

Например, в играх с большим количеством клиентов вы бы назначали выделенные потоки для обработки ввода, но для игр с несколькими клиентами (скажем, <= 16) нет необходимости в нескольких потоках. </p>

В некоторых играх есть NPC со значительным умом. Может быть разумно запускать их в собственных потоках, но если у вас их слишком много, вам понадобится пул потоков, чтобы кучка NPC могла совместно использовать один поток.

Если у вас постоянный мир, вам нужно записать состояние на жесткий диск где-нибудь (возможно, через БД). Так как это имеет серьезные задержки, вам не нужно ждать основного цикла игры на этом вводе / выводе. Тогда это будет другая тема.

Наконец, возникает вопрос, есть ли у вас основной игровой цикл. Будет ли в MMO один цикл, или вы предпочитаете много?

...