Linux pipes

Apollon Oikonomopoulos apoikos at csl.mech.ntua.gr
Tue Sep 23 20:13:24 EEST 2008


Καλησπέρα,

On 18:56 Tue 23 Sep     , Tasos Laskos wrote:
> Kalispera sti lista,
>
> Exo mia aporia/provlima me linux pipes.
> Exo grapsei ena programma to opoio katevazei video kai to stelnei sto  
> stdin tou Kaffeine player.
>
> Px:
> ----------------
> vget --stdout http://www.veoh.com/videos/v6272417ktA6zTWy | kaffeine  
> stdin://
> ----------------
>
> Exo paratirisei omos pos otan patao pause sto Kaffeine to programma  
> kanei episis pause.
> Stamataei akoma kai na katevazei to video, vlepo apo network monitor pos  
> i taxitita peftei sto 0kBps.
>
> To idio ginete kai sto vlc.
>
> Kai i8ela na rotiso, ayto ofeilete sto pipe?
> 8a voleve poly otan pataei o xristis pause sto player tou to progama mou  
> na synexisei na stelnei data
> sto pipe oste o player na to vazei sto buffer tou.

Αυτό οφείλεται στο ότι τα περισσότερα read/write operations γενικά είναι 
blocking. Και εξηγώ: τα pipes είναι buffered, το οποίο σημαίνει ότι 
υπάρχει ένα μέγιστο μέγεθος δεδομένων που μπορούν να γραφτούν στη μια 
πλευρά χωρίς να διαβαστούν από την άλλη. Κάθε φορά που γράφεις κάτι στη 
μια πλευρά του pipe, γεμίζει το buffer, και κάθε φορά που διαβάζεις απ' 
την απέναντι πλευρά, αδειάζει κατά τον αριθμό των bytes που διάβασες. 

Αν τώρα κάποια στιγμή σταματήσεις να διαβάζεις, το άκρο που γράφει 
κάποια στιγμή θα γεμίσει ολόκληρο το buffer που είναι allocated γι' αυτό 
το σκοπό. Μη έχοντας λοιπόν τι άλλο να κάνει, η write() θα περιμένει 
χωρίς να επιστρέφει (αυτό ονομάζεται blocking), μέχρι το process στο 
απέναντι άκρο του pipe να διαβάσει δεδομένα και να αδειάσει λίγο χώρο.  
Σύμφωνα με την manpage της pipe(7), το buffer για τα pipes είναι 4kiB 
για το linux.

Είναι προφανές λοιπόν ότι δεν μπορείς να περιμένεις ότι θα διαβάσεις ένα 
ολόκληρο αρχείο video, θα το γράψεις όλο στη standard output και θα 
περιμένεις να το διαβάσει το απέναντι άκρο. Αυτό που πρέπει να κάνεις 
στην προκειμένη περίπτωση, είναι να κάνεις allocate ένα δικό σου buffer  
το οποίο θα γεμίζεις από το αρχείο που ανεβάζεις. Στη συνέχεια, σε κάθε 
κύκλο θα κοιτάς με τη select() ή την epoll() αν μπορείς να γράψεις στην 
standard output, ή αν έχει γεμίσει το buffer της επειδή το απέναντι άκρο 
έχει σταματήσει να διαβάζει. Αν τώρα κατά τη διάρκεια της αναμονής 
γεμίσει και το δικό σου buffer, τότε θα πρέπει να σταματήσει το 
πρόγραμμά σου να διαβάζει από το δίκτυο μέχρι να ξεμπλοκάρει το απέναντι 
άκρο.

Τα παραπάνω δεν τα έχω κάνει ποτέ στη ζωή μου, απλά είναι ό,τι έχω 
καταλάβει σχετικά με το πως λειτουργούν τα pipes και γενικά τα blocking 
operations.  Οι κατέχοντες ας μας διαφωτίσουν :)

>
> Exei kaneis kapoia idea i kapoio link pou na eksigei ti ginete?
>
> Eyxaristo ek ton proteron,
> Tasos L.
>
>
> --
> linux-greek-users mailing list -- http://lists.hellug.gr

/Απόλλων




More information about the Linux-greek-users mailing list