Le pipeline sono spesso implementate in un sistema operativo multitasking, avviando tutti gli elementi contemporaneamente ai processi e servendo automaticamente le richieste di lettura dei dati di ciascun processo con i dati scritti dal processo upstream – questa può essere chiamata pipeline multiprocessata. In questo modo, la CPU verrà naturalmente commutata tra i processi dallo scheduler in modo da minimizzare il suo tempo di inattività. In altri modelli comuni, gli elementi sono implementati come thread leggeri o come coroutine per ridurre il sovraccarico del sistema operativo spesso coinvolto nei processi. A seconda del sistema operativo, i thread possono essere pianificati direttamente dal sistema operativo o da un gestore di thread. Le coroutine sono sempre programmate da un gestore di coroutine di qualche forma.
Di solito, le richieste di lettura e scrittura sono operazioni di blocco, il che significa che l’esecuzione del processo di origine, al momento della scrittura, viene sospesa fino a quando tutti i dati potrebbero essere scritti nel processo di destinazione e, allo stesso modo, l’esecuzione del processo di destinazione, al momento della lettura, viene sospesa fino a quando Ciò non può portare a un deadlock, in cui entrambi i processi aspetterebbero indefinitamente l’un l’altro per rispondere, poiché almeno uno dei due processi avrà subito dopo la sua richiesta gestita dal sistema operativo e continuerà a funzionare.
Per le prestazioni, la maggior parte dei sistemi operativi che implementano le pipe utilizza buffer di pipe, che consentono al processo di origine di fornire più dati di quelli che il processo di destinazione è attualmente in grado o disposto a ricevere. Nella maggior parte dei sistemi operativi Unix e Unix-like, è disponibile anche un comando speciale che implementa un buffer di pipe di dimensioni potenzialmente molto più grandi e configurabili, tipicamente chiamato “buffer”. Questo comando può essere utile se il processo di destinazione è significativamente più lento del processo di origine, ma è comunque desiderato che il processo di origine possa completare la sua attività il prima possibile. Ad esempio, se il processo di origine è costituito da un comando che legge una traccia audio da un CD e il processo di destinazione è costituito da un comando che comprime i dati audio della forma d’onda in un formato come MP3. In questo caso, il buffering dell’intera traccia in un buffer di pipe consentirebbe all’unità CD di ruotare più rapidamente e consentire all’utente di rimuovere il CD dall’unità prima che il processo di codifica sia terminato.
Tale comando buffer può essere implementato utilizzando le chiamate di sistema per la lettura e la scrittura dei dati. Uno spreco di attesa occupato può essere evitato utilizzando strutture come poll o select o multithreading.
Alcuni esempi notevoli di sistemi software pipeline includono:
- RaftLib – C/C++ Apache 2.0 License