Как устроено в юниксе - не знаю. Но мне кажется, что можно считать корректным следующий подход. Для начала - схема, как это работает в юниксе на уровне пользователя.
Код:
rawdata -> p1 -> stream1 -> p2 -> stream2 -> p3 -> stream3 -> data
-> stream ->
stream - участок потока, влекущий данные между двумя точками их обработки. Стрелка слева символизирует вливание в поток данных, обработанных на предыдущей точке, а справа - загрузка данных на очередную точку.
-> p ->
p - точка, на которой происходит обработка данных.
Стрелка слева символизирует получение данных из предыдущего участка потока, а стрелка справа - возвращение данных в поток на следующий его участок.
Если на конвейере точек обработки не будет, то данные на выходе окажутся такими же, как и на входе.
Как организовать подачу данных на вход и приём их на выходе - отдельная задача, которая решается однозначно не так, как в юниксе: у нас не терминал а ББ. Поэтому решайте её любым удобным для Вас способом.
А подача данных внутри решается довольно просто.
Интерфейс точки обработки данных должен быть таким:
Код:
p = RECORD
prev : StreamSection;
process : ...;
next : StreamSection
END
Точка читает из участка потока данных сколько ей надо, и записывает обработанные данные в следующий участок.
Активным элементом точки должна быть команда ББ так? Она будет обрабатывать данные, пока в предыдущем участке не закончились данные или пока в следующем не закончилось место. Если команда закончила работу, то переходим к команде из следующей точки и т.д.
Ну а интерфейс конвейера такой:
Код:
pipe = RECORD
Add(x : p);
Start()
END
(Сюда не включены процедуры загрузки исходных данных и получения итоговых данных)
Команда Add добавляет вместе с точкой обработки ещё и участок конвейера (автоматически).
P.S. Надеюсь, я понятно описал, а то так поздно, что я уже не уверен, что изъясняюсь внятно.