שיחת מערכת צנרת ב C

Pipe System Call C



צינור() היא פונקציית מערכת לינוקס. ה צינור() פונקציית המערכת משמשת לפתיחת תיאורי קבצים המשמשים לתקשורת בין תהליכי לינוקס שונים. בקיצור, ה צינור() הפונקציה משמשת לתקשורת בין תהליכים בלינוקס. במאמר זה, אני הולך להראות לך כיצד להשתמש בפונקציית מערכת הצינור () בלינוקס. אז בואו נתחיל.

התחביר של ה צינור() הפונקציה היא:







intצינור(intpipefd[2]);

כאן, הפונקציה pipe () יוצרת ערוץ נתונים חד כיווני לתקשורת בין תהליכים. אתה עובר בתוך int מערך מסוג (מספר שלם) pipefd המורכב משני רכיבי מערך לצינור הפונקציה (). ואז הפונקציה pipe () יוצרת שני מתארי קבצים ב- pipefd מַעֲרָך.



המרכיב הראשון של pipefd מַעֲרָך, pipefd [0] משמש לקריאת נתונים מהצינור.



המרכיב השני של pipefd מַעֲרָך, pipefd [1] משמש לכתיבת נתונים לצינור.





לאחר הצלחה הפונקציה pipe () מחזירה 0. אם מתרחשת שגיאה במהלך אתחול הצינור, הפונקציה pipe () מחזירה -1.

הפונקציה pipe () מוגדרת בכותרת העליונה unistd.h . על מנת להשתמש בפונקציה pipe () בתוכנית C שלך, עליך לכלול את הכותרת unistd.h כדלהלן:



#לִכלוֹל

למידע נוסף על פונקציית המערכת של pipe (), בדוק את דף האדם של pipe () באמצעות הפקודה הבאה:

איש $2צינור
דף הגבר של הצינור().

דוגמה 1:

בדוגמה הראשונה, צור קובץ מקור C חדש 1_pipe.c והקלד את שורות הקודים הבאות.

#לִכלוֹל
#לִכלוֹל
#לִכלוֹל

intרָאשִׁי(בָּטֵל) {
intpipefds[2];

אם(צינור(pipefds) == -1) {
perror ('צינור');
יְצִיאָה (EXIT_FAILURE);
}

printf ('קרא ערך תיאור הקבצים: %d n',pipefds[0]);
printf ('כתוב ערך מתאר קובץ: %d n',pipefds[1]);

לַחֲזוֹרEXIT_SUCCESS;
}

כאן, כללתי את קובץ הכותרת של הצינור () unistd.h תחילה עם השורה הבאה.

#לִכלוֹל

ואז, ב רָאשִׁי() פונקציה, הגדרתי את pipefds מערך שלם של שני רכיבים עם השורה הבאה.

intpipefds[2];

לאחר מכן, הפעלתי את הפונקציה pipe () לאתחול מערך תיאורי הקבצים pipefds כדלהלן.

צינור(pipefds)

בדקתי גם שגיאות באמצעות ערך ההחזרה של הפונקציה pipe (). השתמשתי ב- יְצִיאָה() פונקציה כדי לסיים את התוכנית במקרה שפונקציית הצינור נכשלת.

אם(צינור(pipefds) == -1) {
perror ('צינור');
יְצִיאָה (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.c והקלד את שורות הקודים הבאות.

#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
#לִכלוֹל

intרָאשִׁי(בָּטֵל) {
intpipefds[2];
לְהַשְׁחִירבַּלָם[5];

אם(צינור(pipefds) == -1) {
perror ('צינור');
יְצִיאָה (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 תווים ב לְהַשְׁחִיר מַעֲרָך. אורך המערך הוא 5 (כולל התו NULL 0).

לְהַשְׁחִיר *פִּין= '4128 0';

כל תו ASCII הוא בגודל 1 בתים ב- C. לכן, כדי לשלוח את ה- PIN בן 4 הספרות דרך הצינור, עליך לכתוב 5 בתים (4 + 1 תו NULL) של נתונים לתוך הצינור.

כדי לכתוב 5 בתים של נתונים ( פִּין ) לתוך הצינור, השתמשתי ב לִכתוֹב() פונקציה באמצעות מתאר קובץ הצינור pipefds [1] כדלהלן.

לִכתוֹב(pipefds[1],פִּין, 5);

עכשיו כשיש לי כמה נתונים בצינור, אני יכול לקרוא אותם מהצינור באמצעות לקרוא() פונקציה במתאר קובץ הצינור הקריא pipefds [0] . כפי שכתבתי 5 בתים של נתונים ( פִּין ) לתוך הצינור, אקרא גם 5 בתים של נתונים מהצינור. הנתונים הנקראים יישמרו ב- בַּלָם מערך תווים. מכיוון שאקרא 5 בתים של נתונים מהצינור, בַּלָם אורך מערך התווים חייב להיות באורך של 5 בתים לפחות.

הגדרתי את ה בַּלָם מערך תווים בתחילת רָאשִׁי() פוּנקצִיָה.

לְהַשְׁחִירבַּלָם[5];

עכשיו, אני יכול לקרוא את ה- PIN מהצינור ולשמור אותו ב- בַּלָם מערך עם השורה הבאה.

לקרוא(pipefds[0],בַּלָם, 5);

עכשיו לאחר שקראתי את ה- PIN מהצינור, אני יכול להדפיס אותו באמצעות printf () לתפקד כרגיל.

printf ('PIN מהצינור: %s n',בַּלָם);

ברגע שאני מפעיל את התוכנית, הפלט הנכון מוצג כפי שאתה יכול לראות.

דוגמה 3:

צור קובץ מקור C חדש 3_pipe.c כסוג בשורות הקודים הבאות.

#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
intרָאשִׁי(בָּטֵל) {
intpipefds[2];
לְהַשְׁחִיר *פִּין;
לְהַשְׁחִירבַּלָם[5];

אם(צינור(pipefds) == -1) {
perror ('צינור');
יְצִיאָה (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.c כסוג בשורות הקודים הבאות.

#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
#לִכלוֹל
#לִכלוֹל

#הגדר PIN_LENGTH 4
#הגדר PIN_WAIT_INTERVAL 2

בָּטֵלgetPIN(לְהַשְׁחִירפִּין[PIN_LENGTH+ 1]) {
מסר (חולה() +להתבאס());

פִּין[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. תודה שקראת מאמר זה.