2015-09-04 4 views
0

Я пытаюсь написать видеомагнитофон с использованием фронтального и заднего буфера и двух потоков, этот код работает, но его очень сложно отладить многопоточный код, поэтому я не уверен, будет ли этот код работать 100 % раз, я бы очень признателен, если кто-то может это посмотреть и проверить, не пропал ли я что-нибудь.Использование буферов подкачки с boost conditional_variable

Основная идея есть, encode thread ждет frontbuffer в это время нить записи заполняет задний буфер, когда он заканчивается, он переключает буферы. Encode thread - это кодирование переднего буфера, а буфер записи снова заполняет буферный буфер.

boost::mutex frontbuflock_; 
boost::condition_variable ready_cond_; 
raw_buffer_t raw_buf[2]; 
raw_buffer_t* raw_back_buffer_ = 0; 
raw_buffer_t* raw_front_buffer_ = 0; 
boost::atomic_bool front_buffer_ready_; 

void record_thread() 
{ 
    do 
    { 
     int32_t* p = &raw_back_buffer_->at(0); 

     [[[ fill backbuffer with image data here ]]] 

     frontbuflock_.lock(); 

     //swap buffers 
     raw_buffer_t* tmp = raw_front_buffer_; 
     raw_front_buffer_ = raw_back_buffer_; 
     raw_back_buffer_ = tmp; 

     front_buffer_ready_ = 1; 

     ready_cond_.notify_one(); 
     frontbuflock_.unlock(); 

    }while(!stop_); 
} 

void encode_thread() 
{ 
    do 
    { 
     while(!front_buffer_ready_) 
      ready_cond_.wait(lock); 

     frontbuflock_.lock(); 

     [[[ encode frontbuffer here ]]] 

     front_buffer_ready_ = 0; 
     frontbuflock_.unlock(); 
    }while(!stop_); 
} 

ив нашел маленькую вещь, позволяет сказать, что запись нить оповещает состояние переменной и высвобождает frontbuflock, закодировать нить должна блокировать frontbuffer но Theres небольшой вероятность того, что запись нить будет заполнить BackBuffer и заблокировать frontbuffer снова перед шифровать поток будет блокировать его. в этом случае плохо потерять один кадр, я не уверен, что я должен даже беспокоиться об этом.

+0

С быстрым взглядом вы, кажется, используете больше блокировки, чем вам нужно. – JimmyB

+0

Вы слишком много блокируете. Кроме того, для простых данных, таких как boolean flag, которые используются несколькими потоками, вместо атомалов используются атомы. Сравнение-обмен (используется правильно) может значительно улучшить скорость вашего кода. –

ответ

0

Предлагаю вам написать несколько модульных тестов для этого, используя вашу любимую структуру тестирования, а затем запустить тесты в helgrind. Это инструмент для обнаружения ошибок синхронизации, который является частью valgrind: http://valgrind.org/docs/manual/hg-manual.html.

Из моего личного опыта с инструментами valgrind я установил минимальную чувствительность, потому что эти инструменты обычно сообщают много ошибок. Некоторые из них не ваша вина, но библиотеки, которые вы используете. Сначала вы хотите получить низкие висячие фрукты. Как только вы исправили или подавили основные ошибки, переходите к менее серьезным. Rinse & повторить.

Удаленная отладка! :)

Смежные вопросы