استدعاء نظام الأنابيب في C.

Pipe System Call C



يضخ() هي إحدى وظائف نظام Linux. ال يضخ() تُستخدم وظيفة النظام لفتح واصفات الملفات ، والتي تُستخدم للتواصل بين عمليات Linux المختلفة. باختصار ، فإن يضخ() تُستخدم الوظيفة للتواصل بين العمليات في Linux. في هذه المقالة ، سأوضح لك كيفية استخدام وظيفة نظام الأنابيب () في Linux. لذلك دعونا نبدأ.

بناء جملة يضخ() الوظيفة هي:







intيضخ(intالأنابيب[2])؛

هنا ، تقوم وظيفة الأنابيب () بإنشاء قناة بيانات أحادية الاتجاه للاتصال بين العمليات. تمر في int (عدد صحيح) نوع المصفوفة الأنابيب تتكون من عنصري صفيف لأنبوب الوظيفة (). ثم تقوم وظيفة الأنابيب () بإنشاء واصفي ملفين في ملف الأنابيب مجموعة مصفوفة.



العنصر الأول من الأنابيب مجموعة مصفوفة، pipefd [0] يستخدم لقراءة البيانات من الأنبوب.



العنصر الثاني من الأنابيب مجموعة مصفوفة، الأنابيب [1] يستخدم لكتابة البيانات على الأنبوب.





عند النجاح ، ترجع الدالة pipe () القيمة 0. إذا حدث خطأ أثناء تهيئة الأنبوب ، فإن وظيفة pipe () ترجع -1.

يتم تحديد وظيفة الأنابيب () في الرأس unistd.h . من أجل استخدام وظيفة الأنابيب () في برنامج سي الخاص بك ، يجب عليك تضمين الرأس unistd.h على النحو التالي:



#يشمل

لمزيد من المعلومات حول وظيفة نظام الأنابيب () ، تحقق من صفحة دليل الأنبوب () باستخدام الأمر التالي:

رجل دولار2يضخ
صفحة رجل الأنابيب().

مثال 1:

بالنسبة للمثال الأول ، قم بإنشاء ملف مصدر C جديد 1_pipe.c واكتب سطور الرموز التالية.

#يشمل
#يشمل
#يشمل

intالأساسية(فارغ) {
intالأنابيب[2]؛

لو(يضخ(الأنابيب) == -1) {
خوف ('يضخ')؛
خروج (EXIT_FAILURE)؛
}

printf ('قراءة قيمة واصف الملف:٪ dن'والأنابيب[0])؛
printf ('كتابة قيمة واصف الملف:٪ dن'والأنابيب[1])؛

إرجاعEXIT_SUCCESS؛
}

هنا ، قمت بتضمين ملف رأس الأنبوب () unistd.h أولا مع السطر التالي.

#يشمل

ثم في الأساسية() وظيفة ، لقد حددت الأنابيب مصفوفة عدد صحيح مكون من عنصرين مع السطر التالي.

intالأنابيب[2]؛

بعد ذلك ، قمت بتشغيل وظيفة pipe () لتهيئة مجموعة واصفات الملفات الأنابيب على النحو التالي.

يضخ(الأنابيب)

لقد تحققت أيضًا من الأخطاء باستخدام القيمة المرجعة لوظيفة الأنابيب (). لقد استخدمت ملف خروج() تعمل على إنهاء البرنامج في حالة فشل وظيفة الأنبوب.

لو(يضخ(الأنابيب) == -1) {
خوف ('يضخ')؛
خروج (EXIT_FAILURE)؛
}

بعد ذلك ، قمت بطباعة قيمة واصفات ملفات أنبوب القراءة والكتابة الأنابيب [0] و الأنابيب [1] على التوالى.

printf ('قراءة قيمة واصف الملف:٪ dن'والأنابيب[0])؛
printf ('كتابة قيمة واصف الملف:٪ dن'والأنابيب[1])؛

إذا قمت بتشغيل البرنامج ، يجب أن ترى الإخراج التالي. كما ترى ، قيمة واصف ملف أنبوب القراءة الأنابيب [0] يكون 3 واكتب واصف ملف الأنبوب الأنابيب [1] يكون 4 .

المثال 2:

قم بإنشاء ملف مصدر C آخر 2_pipe.c واكتب سطور الرموز التالية.

#يشمل
#يشمل
#يشمل
#يشمل

intالأساسية(فارغ) {
intالأنابيب[2]؛
شارمتعادل[5]؛

لو(يضخ(الأنابيب) == -1) {
خوف ('يضخ')؛
خروج (EXIT_FAILURE)؛
}

شار *دبوس= 4128 0'؛

printf (كتابة PIN إلى الأنبوب ...ن')؛
اكتب(الأنابيب[1]ودبوسو 5)؛
printf ('منتهي.نن')؛

printf (قراءة رقم التعريف الشخصي من الأنبوب ...ن')؛
اقرأ(الأنابيب[0]ومتعادلو 5)؛
printf ('منتهي.نن')؛

printf ('PIN من الأنبوب:٪ sن'ومتعادل)؛

إرجاعEXIT_SUCCESS؛
}

يوضح لك هذا البرنامج بشكل أساسي كيفية الكتابة إلى الأنبوب وقراءة البيانات التي كتبتها من الأنبوب.

هنا ، قمت بتخزين رمز PIN المكون من 4 أحرف في ملف شار مجموعة مصفوفة. طول الصفيف هو 5 (بما في ذلك الحرف NULL 0).

شار *دبوس= 4128 0'؛

يبلغ حجم كل حرف ASCII بايت واحد في C. لذلك ، لإرسال رقم التعريف الشخصي المكون من 4 أرقام عبر الأنبوب ، يجب كتابة 5 بايت (4 + 1 حرف NULL) من البيانات في الأنبوب.

لكتابة 5 بايت من البيانات ( دبوس ) في الأنبوب ، لقد استخدمت ملف اكتب() تعمل باستخدام واصف ملف أنبوب الكتابة الأنابيب [1] على النحو التالي.

اكتب(الأنابيب[1]ودبوسو 5)؛

الآن بعد أن حصلت على بعض البيانات في الأنبوب ، يمكنني قراءتها من الأنبوب باستخدام ملف اقرأ() تعمل على واصف ملف أنبوب القراءة الأنابيب [0] . كما كتبت 5 بايت من البيانات ( دبوس ) في الأنبوب ، سأقرأ 5 بايت من البيانات من الأنبوب أيضًا. سيتم تخزين البيانات التي تمت قراءتها في ملف متعادل مجموعة الأحرف. نظرًا لأنني سأقرأ 5 بايت من البيانات من الأنبوب ، فإن ملف متعادل يجب ألا يقل طول مصفوفة الأحرف عن 5 بايت.

لقد حددت ال متعادل مجموعة الأحرف في بداية ملف الأساسية() وظيفة.

شارمتعادل[5]؛

الآن ، يمكنني قراءة رقم التعريف الشخصي من الأنبوب وتخزينه في ملف متعادل مجموعة مع السطر التالي.

اقرأ(الأنابيب[0]ومتعادلو 5)؛

الآن بعد أن قرأت رقم التعريف الشخصي من الأنبوب ، يمكنني طباعته باستخدام ملف printf () تعمل كالمعتاد.

printf ('PIN من الأنبوب:٪ sن'ومتعادل)؛

بمجرد تشغيل البرنامج ، يتم عرض الإخراج الصحيح كما ترى.

المثال 3:

قم بإنشاء ملف مصدر C جديد 3_ الأنابيب كما اكتب في سطور الرموز التالية.

#يشمل
#يشمل
#يشمل
#يشمل
#يشمل
intالأساسية(فارغ) {
intالأنابيب[2]؛
شار *دبوس؛
شارمتعادل[5]؛

لو(يضخ(الأنابيب) == -1) {
خوف ('يضخ')؛
خروج (EXIT_FAILURE)؛
}

pid_t pid=شوكة()؛

لو(pid== 0) { // في عملية الطفل
دبوس= 4821 0'؛ // PIN للإرسال
أغلق(الأنابيب[0])؛ // إغلاق قراءة fd
اكتب(الأنابيب[1]ودبوسو 5)؛ // اكتب PIN إلى الأنبوب

printf (إنشاء PIN في الطفل وإرساله إلى الوالد ...ن')؛
نايم(2)؛ // تأخير متعمد
خروج (EXIT_SUCCESS)؛
}

لو(pid> 0) { // في العملية الرئيسية
انتظر(باطل)؛ // انتظر حتى تنتهي عملية الطفل
أغلق(الأنابيب[1])؛ // إغلاق الكتابة fd
اقرأ(الأنابيب[0]ومتعادلو 5)؛ // قراءة PIN من الأنبوب
أغلق(الأنابيب[0])؛ // إغلاق قراءة fd

printf ('الوالد تلقى PIN'٪ s 'ن'ومتعادل)؛
}

إرجاعEXIT_SUCCESS؛
}

في هذا المثال ، أوضحت لك كيفية استخدام الأنبوب للتواصل بين العمليات. لقد أرسلت رقم تعريف شخصي من العملية الفرعية إلى العملية الأبوية باستخدام أنبوب. ثم اقرأ رقم التعريف الشخصي من الأنبوب في العملية الأصلية وقم بطباعته من العملية الأصلية.

أولاً ، لقد قمت بإنشاء عملية فرعية باستخدام وظيفة fork ().

pid_t pid=شوكة()؛

ثم ، في عملية الطفل ( معرف المنتج == 0 ) ، لقد كتبت رقم التعريف الشخصي على الأنبوب باستخدام ملف اكتب() وظيفة.

اكتب(الأنابيب[1]ودبوسو 5)؛

بمجرد كتابة رقم التعريف الشخصي على الأنبوب من العملية الفرعية ، فإن العملية الأبوية ( pid> 0 ) اقرأها من الأنبوب باستخدام ملف اقرأ() وظيفة.

اقرأ(الأنابيب[0]ومتعادلو 5)؛

بعد ذلك ، طبعت العملية الأبوية رقم التعريف الشخصي باستخدام printf () تعمل كالمعتاد.

printf ('الوالد تلقى PIN'٪ s 'ن'ومتعادل)؛

كما ترى ، فإن تشغيل البرنامج يعطي النتيجة المتوقعة.

المثال 4:

قم بإنشاء ملف مصدر C جديد 4_أنابيب.ج كما اكتب في سطور الرموز التالية.

#يشمل
#يشمل
#يشمل
#يشمل
#يشمل

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

فارغgetPIN(شاردبوس[PIN_LENGTH+ 1]) {
سراند (getpid() +هراء())؛

دبوس[0] = 49 + صف () ٪ 7؛

ل(intأنا= 1؛أنا<PIN_LENGTH؛أنا++) {
دبوس[أنا] = 48 + صف () ٪ 7؛
}

دبوس[PIN_LENGTH] = ' 0'؛
}


intالأساسية(فارغ) {
في حين(1) {
intالأنابيب[2]؛
شاردبوس[PIN_LENGTH+ 1]؛
شارمتعادل[PIN_LENGTH+ 1]؛

يضخ(الأنابيب)؛

pid_t pid=شوكة()؛

لو(pid== 0) {
getPIN(دبوس)؛ // توليد PIN
أغلق(الأنابيب[0])؛ // إغلاق قراءة fd
اكتب(الأنابيب[1]ودبوسوPIN_LENGTH+ 1)؛ // اكتب PIN إلى الأنبوب

printf (إنشاء PIN في الطفل وإرساله إلى الوالد ...ن')؛

نايم(PIN_WAIT_INTERVAL)؛ // تأخير إنشاء PIN عمداً.

خروج (EXIT_SUCCESS)؛
}

لو(pid> 0) {
انتظر(باطل)؛ // انتظار الطفل للانتهاء

أغلق(الأنابيب[1])؛ // إغلاق الكتابة fd
اقرأ(الأنابيب[0]ومتعادلوPIN_LENGTH+ 1)؛ // قراءة PIN من الأنبوب
أغلق(الأنابيب[0])؛ // إغلاق قراءة fd
printf ('تلقى الوالد PIN'٪ s 'من الطفل.نن'ومتعادل)؛
}
}

إرجاعEXIT_SUCCESS؛
}

هذا المثال هو نفسه مثال 3 . الاختلاف الوحيد هو أن هذا البرنامج ينشئ باستمرار عملية فرعية ، وينشئ رقم تعريف شخصيًا في العملية التابعة ويرسل رقم التعريف الشخصي إلى العملية الأم باستخدام أنبوب.

ثم تقرأ عملية الوالدين رقم التعريف الشخصي من الأنبوب وتطبعه.

يقوم هذا البرنامج بإنشاء PIN_LENGTH PIN جديد كل PIN_WAIT_INTERVAL ثانية.

كما ترى ، يعمل البرنامج بالشكل المتوقع.

يمكنك فقط إيقاف البرنامج بالضغط على + ج .

إذن ، هذه هي الطريقة التي تستخدم بها استدعاء نظام الأنابيب () في لغة البرمجة سي. شكرا لقراءة هذا المقال.