Организация ввода в движке: два потока или один поток?

Discussion in 'Машинное отделение' started by варяг, 26 Oct 2006.

  1. TopicStarter Overlay

    варяг Учаcтник

    • Участник
    Member Since:
    23.10.2006
    Message Count:
    98
    Likes Received:
    0
    Репутация:
    0
    Location:
    Гонду-Раша
    Оффлайн
    Я честно признаюсь раньше с потоками дело не имел, потому и спрашиваю. У меня в программе сейчас 2 потока. Один для ввода (принимает команды от пользователя), во втором потоке должен крутиться движок. Никак не могу настроить потоки так, чтобы быстродействие было бы сопоставимо с однопотоковым приложением. Скорость падает в 2 раза. Это так и должно быть? Пробовал регулировать приоритетами SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL) - пока не помогает. Если задать потоку ввода приоритет THREAD_PRIORITY_BELOW_NORMAL - поток глохнет, ввести ничего нельзя. Когда у обоих потоков приоритет THREAD_PRIORITY_NORMAL все работает, но в 2 раза медленнее. Порылся в MSDN, но кажется испробовал уже все :(
  2. NS Нефёдов Сергей

    • Заслуженный
    • Ветеран
    • Старожил
    Member Since:
    02.05.2006
    Message Count:
    6.811
    Likes Received:
    96
    Репутация:
    3
    Location:
    Санкт-Петербург
    Оффлайн
    Моё мнение - один поток значительно лучше.
  3. WinPooh В.М.

    • Команда форума
    Member Since:
    13.02.2006
    Message Count:
    9.492
    Likes Received:
    3.122
    Репутация:
    95
    Location:
    Москва
    Оффлайн
    Я надеюсь, что у Вас поток, ожидающий ввод, делает это по таймеру, через определённое время?
    А в остальное время вызывает Sleep() или какой-то его аналог?

    Игры с приоритетами процессов - неэлегантно. Это какой-то последний довод уже. Если ничего больше не помогает.

    Хотя и тут возможны разные пакости связанные с размером кванта времени в планировщике.

    Наверное, NS прав - одним потоком проще...
  4. TopicStarter Overlay

    варяг Учаcтник

    • Участник
    Member Since:
    23.10.2006
    Message Count:
    98
    Likes Received:
    0
    Репутация:
    0
    Location:
    Гонду-Раша
    Оффлайн
    Верно, в остальное время вызывает Sleep(), но и это не помогает. Наверное одним потоком действительно проще. Я уже как-то пытался одним потоком все организовать, но, как сейчас помню, были проблемы с организацией Pondering. Здесь какие-нибудь идеи будут?
  5. NS Нефёдов Сергей

    • Заслуженный
    • Ветеран
    • Старожил
    Member Since:
    02.05.2006
    Message Count:
    6.811
    Likes Received:
    96
    Репутация:
    3
    Location:
    Санкт-Петербург
    Оффлайн
    Проверяешь в Search наличие комманды от движка.
    Например один раз в 500 мс. Можно чаще.
    t:=timeGettime;
    if (t-poslT)>=500 Then
    Begin
    poslT:=t;
    // проверяем наличие инфы от движка
    // я делаю это при помощи winAPI - PeekNamedPipe() и т.д.
    end;

    А можно это всё перенести в отдельную ветку?
  6. WildCat Коршунов Игорь

    • Команда форума
    Member Since:
    04.05.2006
    Message Count:
    3.599
    Likes Received:
    4
    Репутация:
    0
    Location:
    Гомель
    Оффлайн
    У меня один поток.
    Как ожидать команд пока нет перебора понятно.
    Если идет перебор, то примерно 10 раз в секунду проверяется наличие команды на вводе:
    Code:
    int IsInputAvailable()
    {
      static int init = 0, pipe;
      static HANDLE inh;
      DWORD dw;
    
      if (!Inter) return 0; // если установлен флаг работать без прерываний
      if (!init) {
        init = 1;
        inh = GetStdHandle(STD_INPUT_HANDLE);
        pipe = !GetConsoleMode(inh, &dw);
        if (!pipe) {
          SetConsoleMode(inh, dw & ~(ENABLE_WINDOW_INPUT));
          FlushConsoleInputBuffer(inh);
          FlushConsoleInputBuffer(inh);
        }
      }
      if(pipe) {
        if(!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
        return dw;
      } else {
        GetNumberOfConsoleInputEvents(inh, &dw);
        return dw <= 1 ? 0 : dw;
      }
    }
    Этот код из Крафти. Более менее работает.
    Далее читаю команду в буфер, и смотрю возможна ли обработка не прерывая вычислений. Если нет, то устанавливаю флаг для окончания перебора. Далее работает обычный код обработки команд. Он первым делом смотрит, есть ли команда в буфере, и только затем берет новую команду со стандартного ввода.
  7. WildCat Коршунов Игорь

    • Команда форума
    Member Since:
    04.05.2006
    Message Count:
    3.599
    Likes Received:
    4
    Репутация:
    0
    Location:
    Гомель
    Оффлайн
    Мне очень трудно понять как может скорость падать в два раза. Ведь поток для ввода практически все время ожидает ввода, т.е. ничего не делает. Ему даже слипы не нужны.
    Покажи код потока ввода. Очень интересно, что ты там натворил.
  8. TopicStarter Overlay

    варяг Учаcтник

    • Участник
    Member Since:
    23.10.2006
    Message Count:
    98
    Likes Received:
    0
    Репутация:
    0
    Location:
    Гонду-Раша
    Оффлайн
    Все, эта тема умерла. Еще вчера я сделал все в одном потоке, прекрасно работает

Share This Page