Ответ 1
Как упоминалось в комментариях, у вас нет большого контроля над планированием. Что, вероятно, может помочь вам еще больше, это отвратиться от спин-замков и условий использования. Это заставит поток визуализации спать, если он пойдет слишком быстро и обработает все данные, полученные потоком захвата. Вы можете посмотреть этот пример для 1-й итерации. В вашем случае каждый раз, когда все данные становятся доступными из потока захвата, вам необходимо вызвать notify_one(). Вы можете использовать версию wait, которая использует только один параметр для вашего случая.
Итак, ваш код станет чем-то вроде этого
std::mutex mutex;
std::condition_variable condition;
std::atomic <bool> rendering (false);
auto render = [&rendering, &display, &signal] (void)
{
// this while loop is not needed anymore because
// we will wait for a signal before doing any drawing
while (not rendering)
{std::this_thread::yield ();};
// first we lock. destructor will unlock for us
std::unique_lock<std::mutex> lock(mutex);
do {
// this will wait until we have been signaled
condition.wait(lock);
// maybe check display.rendering() and exit (depending on your req.)
// process all data available
display.draw (signal);
} while (display.rendering ()); // returns false when user quits
rendering = false;
};
auto capture = [&rendering, &daq] (void)
{
for (int i = daq.read_frequency (); i --> 0;)
daq.record (); // fill the buffer before displaying the signal
rendering = true;
condition.notify_one();
// special note; you can call notify_one() here with
// the mutex lock not acquired.
do {daq.record (); condition.notify_one();}
while (rendering);
daq.stop ();
// signal one more time as the render thread could have
// been in "wait()" call
condition.notify_one();
};
std::thread rendering_thread (render);
std::thread capturing_thread (capture);
rendering_thread.join ();
capturing_thread.join ();
Выполнение этого способа также будет потреблять меньше ресурсов ЦП, поскольку поток рендеринга перейдет в спящий режим, когда нет данных для обработки.