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

Тема в разделе "Машинное отделение", создана пользователем варяг, 26 окт 2006.

  1. TopicStarter Overlay

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

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

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

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

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

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

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

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

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

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

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

    • Команда форума
    Рег.:
    04.05.2006
    Сообщения:
    3.599
    Симпатии:
    4
    Репутация:
    0
    Адрес:
    Гомель
    Оффлайн
    У меня один поток.
    Как ожидать команд пока нет перебора понятно.
    Если идет перебор, то примерно 10 раз в секунду проверяется наличие команды на вводе:
    Код:
    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 Коршунов Игорь

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

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

    • Участник
    Рег.:
    23.10.2006
    Сообщения:
    98
    Симпатии:
    0
    Репутация:
    0
    Адрес:
    Гонду-Раша
    Оффлайн
    Все, эта тема умерла. Еще вчера я сделал все в одном потоке, прекрасно работает

Поделиться этой страницей