Предыстория:
Купил я себе пишущий dvd (dvd+-r,dvd+-rw,dvd-ram) и начал его раздуплять под linux. По аналогии с cd-rw я даже не пробовал графические фронтэнды,
а сразу начал делать набор скриптов на dvd+rw-tools. Сделал, работает. Только проблема небольшая вылезла -
у growisofs нет встроенного буфера и при клонировании диска налету скорость записи прыгает скачкообразно соотвественно скорости
чтения с исходного диска.
Немного гугля дало мне кодdd -obs
который не прошёл проверки,а дал даже обратные результаты. Вот я и решил написать свою утилиту буферизирования трубы(pipe).
Она должна была читать данные из stdin, пропускать их через буфер FIFO и отдавать в stdout.
Особенность - ввод и вывод не должны блокировать друг друга. Иначе говоря заблокированный вывод не должен мешать заполняться очереди и
временное отсутствие входных данных не должно мешать очереди опустошаться. Ограничением ввода является размер входной очереди утилиты,
а вывода - следующий по трубе процесс.
Название файла сформировалось даже несколько исторически: pipe buffer non sleeping - первая версия была с использованием usleep,
которому на смену пришла condition variable
Код
Программа использует столько памяти сколько необходимо в данный момент. В случае невозможности выделения памяти программа ведёт
себя так же, как при окончании входных данных - выводит оставшийся буфер и завершает работу.
Возможно логичней было бы выделить всю память сразу и застраховать себя от проблемы нехватки памяти.
Компилируемgcc -O3 ./pbns.c -o pbns -lpthread
Ппроверить утилиту можно тестовой программкой
Запустив напримерcat /dev/zero | ./pbns 32 |./test
Сравнивал sha1sum входного и выходного файла - сходятся. Клонил и dvd-rw со сверкой sha1sum - тоже сходятся :)