Создание независимого потока отрисовки с использованием pthreads (C ++) - PullRequest
1 голос
/ 20 апреля 2010

Я работаю над графическим приложением, которое выглядит примерно так:

while (Simulator.simulating)
{
    Simulator.update();
    InputManager.processInput();
    VideoManager.draw();
}

Я делаю это несколько раз в секунду, и в подавляющем большинстве случаев мои вычисления будут занимать 90 - 99% моего времени обработки.То, что я хотел бы сделать, это вынуть функции processInput и draw и заставить каждую из них работать независимо.

Таким образом, я могу иметь поток ввода, всегда проверяющий ввод (с разумной скоростью), и отрисовкупоток пытается перерисовать с заданной частотой кадров.

Симулятор уже (внутренне) многопоточный, и нет проблем с несколькими потоками, записывающими в одни и те же данные (каждый обрабатывает сегмент).

Моя проблема в том, что я не уверен, как правильно это сделать.Как правильно инициализировать мой pthread_t и связанный с ним pthread_attr_t, чтобы поток работал без блокировки того, что я делаю?Другими словами, как я могу создать два потока, каждый из которых выполняет бесконечный цикл?

Чтобы обобщить еще больше, я пытаюсь выяснить, как это сделать:

for (int i = 0; i < threads; i++)
    pthread_create(&th[i], NULL, func[i], NULL)

for (int i = 0; i < threads; i++)
    pthread_join(th[i], NULL);

Где func [i] - это произвольная функция, которая выполняется в бесконечном цикле и выполняет какую-то произвольную вещь.

Любая помощь или даже ссылка приветствуются, спасибо!

Редактировать: я должен упомянуть об этомЭто интерактивный симулятор, поэтому мне нужно, чтобы два бесконечных цикла работали независимо друг от друга.Кажется, я бегу только сразу.

Ответы [ 2 ]

1 голос
/ 20 апреля 2010

Двойная буферизация - ваш друг здесь. Есть 2 буфера данных. Один из них - буфер рисования, а другой - буфер вычислений. Когда вы закончите вычисления, подождите, пока закончится текущий розыгрыш, а затем поменяйте местами буферы. Теперь он продолжит рисовать вновь рассчитанные данные, пока вы вычисляете данные следующих кадров. Рисование и симуляция теперь почти полностью отделены ...

0 голосов
/ 20 апреля 2010

Сначала я бы предложил использовать boost :: thread в отличие от pthreads, так как вы используете C ++. С boost::thread вы можете сделать что-то вроде этого:

#include <boost/thread.hpp>

void input_thread()
{
    //...
}

void draw_thread()
{
    //...
}

int main()
{
    boost::thread input_th(&input_thread);
    boost::thread draw_th(&draw_thread);

    input_th.join();
    draw_th.join();

    return 0;
}

Конструктор boost::thread автоматически порождает новый поток и вызывает переданную функцию. Вы также можете использовать функции-члены как потоки, используя boost :: bind . Функциональные блоки объединения до выхода из потока. Это необходимо, потому что, если main() завершается, все ваши потоки уничтожаются.

Надеюсь, это поможет вам начать, но самая сложная часть - это синхронизация (обмен данными между потоками). Я предлагаю вам взглянуть на документацию для мьютексов и условных переменных. Помните, что вам нужно убедиться, что только один поток записывает в одну и ту же область памяти одновременно. Мьютексы помогают решить эту проблему. Условные переменные помогают, позволяя вам сигнализировать и ждать сигналов между потоками.

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

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