Κλήση συστήματος σωλήνων στο C

Pipe System Call C



σωλήνας() είναι μια λειτουργία συστήματος Linux. ο σωλήνας() Η λειτουργία συστήματος χρησιμοποιείται για το άνοιγμα περιγραφών αρχείων, οι οποίοι χρησιμοποιούνται για την επικοινωνία μεταξύ διαφορετικών διαδικασιών Linux. Εν ολίγοις, το σωλήνας() Η συνάρτηση χρησιμοποιείται για επικοινωνία μεταξύ διεργασιών στο Linux. Σε αυτό το άρθρο, θα σας δείξω πώς να χρησιμοποιήσετε τη λειτουργία συστήματος pipe () στο Linux. Λοιπόν, ας ξεκινήσουμε.

Η σύνταξη του σωλήνας() η λειτουργία είναι:







intσωλήνας(intpipefd[2])?

Εδώ, η συνάρτηση pipe () δημιουργεί ένα μονοκατευθυντικό κανάλι δεδομένων για επικοινωνία μεταξύ διεργασιών. Περνάς σε ένα int Πίνακας τύπου (ακέραιος) pipefd που αποτελείται από 2 στοιχεία πίνακα στο σωλήνα συνάρτησης (). Στη συνέχεια, η συνάρτηση pipe () δημιουργεί δύο περιγραφείς αρχείων στο pipefd πίνακας.



Το πρώτο στοιχείο του pipefd πίνακας, pipefd [0] χρησιμοποιείται για την ανάγνωση δεδομένων από το σωλήνα.



Το δεύτερο στοιχείο του pipefd πίνακας, pipefd [1] χρησιμοποιείται για την εγγραφή δεδομένων στον σωλήνα.





Με επιτυχία, η συνάρτηση σωλήνα () επιστρέφει 0. Εάν παρουσιαστεί σφάλμα κατά την εκκίνηση του σωλήνα, τότε η συνάρτηση σωλήνα () επιστρέφει -1.

Η συνάρτηση σωλήνα () ορίζεται στην κεφαλίδα unistd.h Το Για να χρησιμοποιήσετε τη λειτουργία pipe () στο πρόγραμμα C, πρέπει να συμπεριλάβετε την κεφαλίδα unistd.h ως εξής:



#περιλαμβάνω

Για περισσότερες πληροφορίες σχετικά με τη λειτουργία του συστήματος σωλήνων (), ελέγξτε τη σελίδα man του σωλήνα () με την ακόλουθη εντολή:

$ man2σωλήνας
Η ανδρική σελίδα του pipe()Το

Παράδειγμα 1:

Για το πρώτο παράδειγμα, δημιουργήστε ένα νέο αρχείο προέλευσης C 1_pipe.γ και πληκτρολογήστε τις ακόλουθες γραμμές κωδικών.

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

intκύριος(κενός) {
intpipefds[2]?

αν(σωλήνας(pipefds) == -1) {
λάθος ('σωλήνας')?
έξοδος (EXIT_FAILURE)?
}

printf ('Διαβάστε Τιμή Περιγραφής Αρχείου: %d n',pipefds[0])?
printf ('Γράψτε Περιγραφέας Αρχείου Τιμή: %d n',pipefds[1])?

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Εδώ, συμπεριέλαβα το αρχείο κεφαλίδας του σωλήνα () unistd.h πρώτα με την ακόλουθη γραμμή.

#περιλαμβάνω

Στη συνέχεια, στο κύριος() συνάρτηση, ορίζω το pipefds ακέραιος πίνακας δύο στοιχείων με την ακόλουθη γραμμή.

intpipefds[2]?

Στη συνέχεια, έτρεξα τη λειτουργία pipe () για να προετοιμάσω τον πίνακα περιγραφών αρχείων pipefds ως εξής.

σωλήνας(pipefds)

Έλεγξα επίσης για σφάλματα χρησιμοποιώντας την τιμή επιστροφής της συνάρτησης σωλήνα (). Χρησιμοποίησα το έξοδος() να τερματίσει το πρόγραμμα σε περίπτωση που η λειτουργία του σωλήνα αποτύχει.

αν(σωλήνας(pipefds) == -1) {
λάθος ('σωλήνας')?
έξοδος (EXIT_FAILURE)?
}

Στη συνέχεια, εκτύπωσα την αξία των περιγραφών αρχείων ανάγνωσης και εγγραφής σωλήνων pipefds [0] και pipefds [1] αντίστοιχα.

printf ('Διαβάστε Τιμή Περιγραφής Αρχείου: %d n',pipefds[0])?
printf ('Γράψτε Περιγραφέας Αρχείου Τιμή: %d n',pipefds[1])?

Εάν εκτελείτε το πρόγραμμα, θα πρέπει να δείτε την ακόλουθη έξοδο. Όπως μπορείτε να δείτε, η τιμή του περιγραφέα αρχείου σωλήνα ανάγνωσης pipefds [0] είναι 3 και γράψτε περιγραφέα αρχείων σωλήνων pipefds [1] είναι 4 Το

Παράδειγμα 2:

Δημιουργήστε ένα άλλο αρχείο προέλευσης C 2_pipe.γ και πληκτρολογήστε τις ακόλουθες γραμμές κωδικών.

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

intκύριος(κενός) {
intpipefds[2]?
απανθρακώνωρυθμιστής[5]?

αν(σωλήνας(pipefds) == -1) {
λάθος ('σωλήνας')?
έξοδος (EXIT_FAILURE)?
}

απανθρακώνω *καρφίτσα= '4128 0'?

printf ('Γράφοντας PIN σε σωλήνα ... n')?
γράφω(pipefds[1],καρφίτσα, 5)?
printf ('Εγινε. n n')?

printf («Ανάγνωση PIN από σωλήνα ... n')?
ανάγνωση(pipefds[0],ρυθμιστής, 5)?
printf ('Εγινε. n n')?

printf ('PIN από το σωλήνα: %s n',ρυθμιστής)?

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Αυτό το πρόγραμμα βασικά σας δείχνει πώς να γράφετε στο σωλήνα και να διαβάζετε τα δεδομένα που έχετε γράψει από το σωλήνα.

Εδώ, έχω αποθηκεύσει έναν κωδικό PIN 4 χαρακτήρων σε a απανθρακώνω πίνακας. Το μήκος του πίνακα είναι 5 (συμπεριλαμβανομένου του χαρακτήρα NULL 0).

απανθρακώνω *καρφίτσα= '4128 0'?

Κάθε χαρακτήρας ASCII έχει μέγεθος 1 byte σε C. Έτσι, για να στείλετε το 4ψήφιο PIN μέσω του σωλήνα, πρέπει να γράψετε 5 byte (4 + 1 NULL χαρακτήρα) δεδομένων στο σωλήνα.

Για να γράψετε 5 byte δεδομένων ( καρφίτσα ) στον σωλήνα, χρησιμοποίησα το γράφω() λειτουργία χρησιμοποιώντας τον περιγραφέα αρχείου εγγραφής σωλήνα pipefds [1] ως εξής.

γράφω(pipefds[1],καρφίτσα, 5)?

Τώρα που έχω κάποια δεδομένα στο σωλήνα, μπορώ να τα διαβάσω από το σωλήνα χρησιμοποιώντας το ανάγνωση() λειτουργία στον περιγραφέα αρχείου σωλήνα ανάγνωσης pipefds [0] Το Όπως έχω γράψει 5 byte δεδομένων ( καρφίτσα ) στο σωλήνα, θα διαβάσω επίσης 5 bytes δεδομένων από το σωλήνα. Τα δεδομένα που διαβάζονται θα αποθηκευτούν στο ρυθμιστής πίνακας χαρακτήρων. Όπως θα διαβάσω 5 byte δεδομένων από το σωλήνα, το ρυθμιστής Ο πίνακας χαρακτήρων πρέπει να έχει μήκος τουλάχιστον 5 byte.

Έχω ορίσει το ρυθμιστής πίνακας χαρακτήρων στην αρχή του κύριος() λειτουργία.

απανθρακώνωρυθμιστής[5]?

Τώρα, μπορώ να διαβάσω το PIN από το σωλήνα και να το αποθηκεύσω στο ρυθμιστής πίνακα με την ακόλουθη γραμμή.

ανάγνωση(pipefds[0],ρυθμιστής, 5)?

Τώρα που διάβασα το PIN από το σωλήνα, μπορώ να το εκτυπώσω χρησιμοποιώντας το printf () λειτουργεί ως συνήθως.

printf ('PIN από το σωλήνα: %s n',ρυθμιστής)?

Μόλις εκτελέσω το πρόγραμμα, εμφανίζεται η σωστή έξοδος όπως μπορείτε να δείτε.

Παράδειγμα 3:

Δημιουργήστε ένα νέο αρχείο προέλευσης C 3_pipe.γ πληκτρολογήστε τις ακόλουθες γραμμές κωδικών.

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
intκύριος(κενός) {
intpipefds[2]?
απανθρακώνω *καρφίτσα?
απανθρακώνωρυθμιστής[5]?

αν(σωλήνας(pipefds) == -1) {
λάθος ('σωλήνας')?
έξοδος (EXIT_FAILURE)?
}

pid_t pid=πιρούνι()?

αν(pid== 0) { // σε παιδική διαδικασία
καρφίτσα= '4821 0'? // PIN για αποστολή
Κλείσε(pipefds[0])? // κλείσιμο ανάγνωσης fd
γράφω(pipefds[1],καρφίτσα, 5)? // εγγραφή PIN στο σωλήνα

printf («Δημιουργία PIN σε παιδί και αποστολή στον γονέα ... n')?
ύπνος(2)? // σκόπιμη καθυστέρηση
έξοδος (EXIT_SUCCESS)?
}

αν(pid>> 0) { // στην κύρια διαδικασία
Περίμενε(ΜΗΔΕΝΙΚΟ)? // περιμένετε να τελειώσει η διαδικασία για παιδιά
Κλείσε(pipefds[1])? // κλείσιμο εγγραφής fd
ανάγνωση(pipefds[0],ρυθμιστής, 5)? // διαβάστε το PIN από το σωλήνα
Κλείσε(pipefds[0])? // κλείσιμο ανάγνωσης fd

printf ('Ο γονέας έλαβε PIN'%s ' n',ρυθμιστής)?
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Σε αυτό το παράδειγμα, σας έδειξα πώς να χρησιμοποιείτε το σωλήνα για επικοινωνία μεταξύ διαδικασιών. Έχω στείλει ένα PIN από τη διαδικασία του παιδιού στη διαδικασία του γονέα χρησιμοποιώντας έναν σωλήνα. Στη συνέχεια, διαβάστε το PIN από το σωλήνα στη διαδικασία γονέα και εκτυπώστε το από τη γονική διαδικασία.

Πρώτον, δημιούργησα μια θυγατρική διαδικασία χρησιμοποιώντας τη λειτουργία πιρούνι ().

pid_t pid=πιρούνι()?

Στη συνέχεια, στη διαδικασία του παιδιού ( pid == 0 ), Έγραψα το PIN στο σωλήνα χρησιμοποιώντας το γράφω() λειτουργία.

γράφω(pipefds[1],καρφίτσα, 5)?

Μόλις γραφεί το PIN στο σωλήνα από τη θυγατρική διαδικασία, η διαδικασία γονέα ( pid> 0 ) Διαβάστε το από το σωλήνα χρησιμοποιώντας το ανάγνωση() λειτουργία.

ανάγνωση(pipefds[0],ρυθμιστής, 5)?

Στη συνέχεια, η διαδικασία γονέα εκτύπωσε το PIN χρησιμοποιώντας printf () λειτουργεί ως συνήθως.

printf ('Ο γονέας έλαβε PIN'%s ' n',ρυθμιστής)?

Όπως μπορείτε να δείτε, η εκτέλεση του προγράμματος δίνει το αναμενόμενο αποτέλεσμα.

Παράδειγμα 4:

Δημιουργήστε ένα νέο αρχείο προέλευσης C 4_pipe.γ πληκτρολογήστε τις ακόλουθες γραμμές κωδικών.

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

κενόςgetPIN(απανθρακώνωκαρφίτσα[PIN_LENGTH+ 1]) {
srand (χάλια() +χορταίνω())?

καρφίτσα[0] = 49 + σειρά () % 7?

Για(intΕγώ= 1?Εγώ<PIN_LENGTH?Εγώ++) {
καρφίτσα[Εγώ] = 48 + σειρά () % 7?
}

καρφίτσα[PIN_LENGTH] = ' 0'?
}


intκύριος(κενός) {
ενώ(1) {
intpipefds[2]?
απανθρακώνωκαρφίτσα[PIN_LENGTH+ 1]?
απανθρακώνωρυθμιστής[PIN_LENGTH+ 1]?

σωλήνας(pipefds)?

pid_t pid=πιρούνι()?

αν(pid== 0) {
getPIN(καρφίτσα)? // δημιουργία PIN
Κλείσε(pipefds[0])? // κλείσιμο ανάγνωσης fd
γράφω(pipefds[1],καρφίτσα,PIN_LENGTH+ 1)? // εγγραφή PIN στο σωλήνα

printf («Δημιουργία PIN σε παιδί και αποστολή στον γονέα ... n')?

ύπνος(PIN_WAIT_INTERVAL)? // καθυστέρηση σκόπιμης δημιουργίας PIN.

έξοδος (EXIT_SUCCESS)?
}

αν(pid>> 0) {
Περίμενε(ΜΗΔΕΝΙΚΟ)? // περιμένοντας να τελειώσει το παιδί

Κλείσε(pipefds[1])? // κλείσιμο εγγραφής fd
ανάγνωση(pipefds[0],ρυθμιστής,PIN_LENGTH+ 1)? // διαβάστε το PIN από το σωλήνα
Κλείσε(pipefds[0])? // κλείσιμο ανάγνωσης fd
printf ('Ο γονέας έλαβε PIN'%s 'από το παιδί. n n',ρυθμιστής)?
}
}

ΕΠΙΣΤΡΟΦΗEXIT_SUCCESS?
}

Αυτό το παράδειγμα είναι το ίδιο με αυτό Παράδειγμα 3 Το Η μόνη διαφορά είναι ότι αυτό το πρόγραμμα δημιουργεί συνεχώς μια παιδική διαδικασία, δημιουργεί ένα PIN στη θυγατρική διαδικασία και στέλνει το PIN στη γονική διαδικασία χρησιμοποιώντας έναν σωλήνα.

Στη συνέχεια, η διαδικασία γονέα διαβάζει το PIN από το σωλήνα και το εκτυπώνει.

Αυτό το πρόγραμμα δημιουργεί ένα νέο PIN_LENGTH PIN κάθε PIN_WAIT_INTERVAL δευτερόλεπτα.

Όπως μπορείτε να δείτε, το πρόγραμμα λειτουργεί όπως αναμενόταν.

Μπορείτε να διακόψετε το πρόγραμμα μόνο πατώντας + ντο Το

Έτσι, αυτός είναι ο τρόπος με τον οποίο χρησιμοποιείτε την κλήση συστήματος pipe () στη γλώσσα προγραμματισμού C. Ευχαριστώ που διαβάσατε αυτό το άρθρο.