Задание № 2904

Студент

Ванданов Сергей

Задача

Очередь изображений

Состояние

Завершено

Баллов

3

Назначено

17.12.2020, 04:23

Завершено

23.12.2020, 12:05

Разработать класс, позволяющий производить многопоточное буферизированное чтение данных. Данные читаются/пишутся блоками фиксированного размера. Типичный пример подобных данных - последовательность несжатых изображений одинакового размера (например, в формате bmp).

Постановка задачи

Задание предполагает одновременную работу двух потоков выполнения: один поток (поток-читатель) считывает данные в очередь, второй (поток-писатель) - с некоторой периодичностью проверяет очередь, выбирает из неё очередные данные, и записывает их в файлы.

Очередь выполняет здесь роль регулятора, который:

  • позволяет согласовать скорости чтения и записи данных между потоками,
  • гарантирует порядок и целостность передаваемых данных.
  • синхронизирует доступ к данным из разных потоков выполнения.

Класс очереди должен быть спроектирован в рамках концепции RAII, и являться владельцем буфера данных.

Примерный прототип класса очереди:

class ImageFIFO {
   ImageFIFO(size_t blockSize, size_t maxBlocks);
   ~ImageFIFO();
   void * getFree();
   void addReady(void * data);
   void * getReady();
   void addFree(void *data);
};
  • ImageFIFO(blockSize, maxBlocks) - выделяет буфер данных, с заданным размером блока, и с фиксированным количеством блоков.
  • ~ImageFIFO() - деструктор, освобождает память.
  • getFree() - метод, вызываемый потоком-писателем, для получения указателя на очередной свободный блок данных.
  • addReady(data) - метод, вызываемый потоком-писателем, помечающий, что найденный ранее блок данных заполнен и готов к передаче.
  • getReady() - метод, вызываемый потоком-читателем, для получения указателя на очередной готовый блок данных.
  • addFree(data) - метод, вызываемый потоком-читателем, помечающий, что выданный ранее блок данных обработан, освобождён и может повторно использоваться очередью.

Тестирование

Необходимо реализовать ряд тестов в порядке усложнения:

  • в каждом тесте на вход очереди подаются блоки данных фиксированной длинны (например изображения с диска, считанные с бинарном режиме), а на выходе - эти данные накапливаются (например сохраняются на диск в бинарном режиме, как файлы изображений), и по окончании передачи проводится побайтовая сверка соответствующих блоков.
  • для базовой проверки функционала обязателен однопоточный тест, поочерёдное чтение/запись в одном потоке.
  • также необходим многопоточный тест, где чтение/запись производятся из разных потоков.

Дополнительный бал за тест на "необычные" модели поведения потоков читателя и писателя:

  • тест на переполнение очереди потоком-писателем.
  • писатель много раз вызывает getFree(), затем заполняет данные, а затем в произвольном порядке помечает блоки как готовые вызовами addReady().
  • тест на опустошении очереди потоком-читателем.
  • читатель много раз вызывает getReady(), сохраняет данные, а затем в произвольном порядке помечает блоки как свободные вызовами addFree().

Ещё один дополнительный бал за предусмотренную возможность отслеживать выходы за пределы буфера.

Действия