Разработать класс, позволяющий производить многопоточное буферизированное чтение данных. Данные читаются блоками произвольного размера, произвольное количество блоков за раз. Типичный пример подобных данных - последовательность сжатых изображений разного размера (например, в формате jpeg).
Задание предполагает одновременную работу двух потоков выполнения: один поток (поток-читатель) считывает данные в очередь, второй (поток-писатель) - с некоторой периодичностью проверяет очередь, выбирает из неё очередные данные, и записывает их в файлы.
Очередь выполняет здесь роль регулятора, который:
Класс очереди должен быть спроектирован в рамках концепции RAII, и являться владельцем буфера данных.
Примерный прототип класса очереди:
class DataFIFO {
DataFIFO(size_t bufferSize, size_t maxBlocks);
~DataFIFO();
void * getFree(size_t size);
void addReady(void * data);
void * getReady(size_t & size);
void addFree(void * data);
};
DataFIFO(bufferSize, maxBlocks)
- выделяет буфер данных заданного размера, с максимальным количеством блоков.~DataFIFO()
- деструктор, освобождает память.getFree(size)
- метод, вызываемый потоком-писателем, для проверки наличия size
свободных байт для данных. Если требуемое количество байт свободно, то функция возвращает начальный адрес блока, иначе null
.addReady(data)
- метод, вызываемый потоком-писателем, помечающий, что запрошенный ранее блок заполнен и готов к передаче. getReady(size)
- метод, вызываемый потоком-читателем, для получения указателя на очередной готовый блок данных. Если готового блока нет, то функция возвращает null
. Через входной аргумент size
возвращается размер блока.addFree(data)
- метод, вызываемый потоком-читателем, помечающий, что полученный ранее блок данных обработан, место освобождёно и может повторно использоваться очередью.Необходимо реализовать ряд тестов в порядке усложнения:
Дополнительный бал за тест на "необычные" паттерны поведения потоков читателя и писателя:
getFree()
, затем заполняет данные, а
затем в произвольном порядке помечает блоки как готовые вызовами
addReady()
.getReady()
, сохраняет данные, а затем
в произвольном порядке помечает блоки как свободные вызовами
addFree()
.