استدعاء نظام الشوكة في C

Fork System Call C



يتم استخدام استدعاء نظام fork () لإنشاء عمليات تابعة في برنامج C. تُستخدم fork () حيث تكون المعالجة المتوازية مطلوبة في التطبيق الخاص بك. يتم تحديد وظيفة نظام fork () في الرؤوس sys / types.h و unistd.h . في البرنامج الذي تستخدم فيه fork ، يجب عليك أيضًا استخدام انتظار () system call. انتظار () يتم استخدام استدعاء النظام للانتظار في العملية الأصلية حتى تنتهي العملية الفرعية. لإنهاء عملية تابعة ، يتم استخدام استدعاء نظام exit () في العملية التابعة. يتم تحديد وظيفة الانتظار () في الرأس sys / انتظر ويتم تحديد وظيفة exit () في الرأس stdlib.h .

الشكل 1: سير عمل مفترق أساسي ()

الشكل 1: سير عمل مفترق أساسي ()







في هذه المقالة ، سأوضح لك كيفية استخدام استدعاء النظام fork () لإنشاء عمليات فرعية في C. لذا ، فلنبدأ.



fork () النحو وقيمة الإرجاع:

تكون صيغة وظيفة نظام fork () كما يلي:



شوكة pid_t(فارغ)؛

لا تقبل وظيفة النظام fork () أي وسيطة. تقوم بإرجاع عدد صحيح من النوع pid_t .





عند النجاح ، تُرجع الدالة fork () PID للعملية الفرعية التي تكون أكبر من 0. داخل العملية الفرعية ، تكون القيمة المرجعة هي 0. إذا فشلت fork () ، فإنها تُرجع -1.

شوكة بسيطة () مثال:

مثال على مفترق بسيط () موضح أدناه:



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

intالأساسية(فارغ) {
pid_t pid=شوكة()؛

لو(pid== 0) {
printf ('التابع => PPID:٪ d PID:٪ dن'وهراء()وgetpid())؛
خروج (EXIT_SUCCESS)؛
}
آخر لو(pid> 0) {
printf ('الأصل => PID:٪ dن'وgetpid())؛
printf (في انتظار انتهاء عملية الطفل.ن')؛
انتظر(باطل)؛
printf (انتهت عملية الطفل.ن')؛
}
آخر {
printf (غير قادر على إنشاء عملية تابعة.ن')؛
}

إرجاعEXIT_SUCCESS؛
}

هنا ، استخدمت fork () لإنشاء عملية فرعية من العملية الرئيسية / الرئيسية. بعد ذلك ، قمت بطباعة PID (معرّف العملية) و PPID (معرّف العملية الأصل) من عملية الطفل والوالد. في عملية الوالدين ، يتم استخدام الانتظار (NULL) لانتظار انتهاء العملية الفرعية. في العملية الفرعية ، يتم استخدام exit () لإنهاء العملية الفرعية. كما ترى ، فإن PID للعملية الأصل هو PPID للعملية الفرعية. لذلك ، عملية الطفل 24738 ينتمي إلى عملية الوالدين 24731 .

يمكنك أيضًا استخدام الوظائف لجعل برنامجك أكثر نمطية. هنا ، كنت processTask () و مهمة الوالدين () وظائف لعمليات الطفل والوالد على التوالي. هذه هي طريقة استخدام fork () فعليًا.

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

فارغالطفل() {
printf ('مرحبا بالعالمن')؛
}

فارغالوالدين() {
printf (المهمة الرئيسية.ن')؛
}

intالأساسية(فارغ) {
pid_t pid=شوكة()؛

لو(pid== 0) {
الطفل()؛
خروج (EXIT_SUCCESS)؛
}
آخر لو(pid> 0) {
انتظر(باطل)؛
الوالدين()؛
}
آخر {
printf ('غير قادر على إنشاء عملية تابعة.')؛
}

إرجاعEXIT_SUCCESS؛
}

مخرجات البرنامج أعلاه:

تشغيل عمليات فرعية متعددة باستخدام fork () و Loop:

يمكنك أيضًا استخدام التكرار الحلقي لإنشاء أكبر عدد تريده من العمليات الفرعية. في المثال أدناه ، قمت بإنشاء 5 عمليات فرعية باستخدام حلقة for. لقد قمت أيضًا بطباعة PID و PPID من العمليات التابعة.

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

intالأساسية(فارغ) {
ل(intأنا= 1؛أنا<= 5؛أنا++) {
pid_t pid=شوكة()؛

لو(pid== 0) {
printf ('العملية الفرعية => PPID =٪ d ، PID =٪ dن'وهراء()وgetpid())؛
خروج (0)؛
}
آخر {
printf ('العملية الأصل => PID =٪ dن'وgetpid())؛
printf (في انتظار انتهاء العمليات الفرعية ...ن')؛
انتظر(باطل)؛
printf (انتهت عملية الطفل.ن')؛
}
}

إرجاعEXIT_SUCCESS؛
}

كما ترى ، فإن معرّف العملية الأصل هو نفسه في جميع العمليات الفرعية. لذلك ، كلهم ​​ينتمون إلى نفس الوالد. كما أنها تنفذ بطريقة خطية. واحدًا تلو الآخر. يعتبر التحكم في عمليات الطفل مهمة معقدة. إذا تعلمت المزيد عن برمجة نظام Linux وكيف تعمل ، فستتمكن من التحكم في تدفق هذه العمليات بأي طريقة تريدها.

مثال من الحياة الواقعية:

تتطلب الحسابات الرياضية المعقدة المختلفة مثل md5 و sha256 وما إلى ذلك توليد التجزئة الكثير من قوة المعالجة. بدلاً من حساب أشياء من هذا القبيل في نفس العملية مثل البرنامج الرئيسي ، يمكنك فقط حساب التجزئة على عملية فرعية وإعادة التجزئة إلى العملية الرئيسية.

في المثال التالي ، قمت بإنشاء رمز PIN المكون من 4 أرقام في عملية فرعية وأرسله إلى العملية الرئيسية ، البرنامج الرئيسي. ثم قمت بطباعة رمز PIN من هناك.

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

intgetPIN() {
// استخدم PPID و PID كبذرة
سراند (getpid() +هراء())؛
intسر= 1000 + صف () ٪ 9000؛
إرجاعسر؛
}

intالأساسية(فارغ) {
intفد[2]؛
يضخ(فد)؛
pid_t pid=شوكة()؛

لو(pid> 0) {
أغلق(0)؛
أغلق(فد[1])؛
بعد، بعدما(فد[0])؛

intالرقم السري؛
size_treadBytes=اقرأ(فد[0]و &الرقم السريو حجم(الرقم السري))؛

printf (في انتظار رقم التعريف الشخصي ...ن')؛
انتظر(باطل)؛
printf (تمت قراءة البايت:٪ ldن'وreadBytes)؛
printf ('PIN:٪ dن'والرقم السري)؛
}
آخر لو(pid== 0) {
أغلق(1)؛
أغلق(فد[0])؛
بعد، بعدما(فد[1])؛

intسر=getPIN()؛
اكتب(فد[1]و &سرو حجم(سر))؛
خروج (EXIT_SUCCESS)؛
}

إرجاعEXIT_SUCCESS؛
}

كما ترى ، في كل مرة أقوم بتشغيل البرنامج ، أحصل على رمز PIN مختلف مكون من 4 أرقام.

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