حلقة لا نهائية

في برمجة الحاسوب ، تُعرف الحلقة اللانهائية (أو الحلقة التي لا نهاية لها ) [ 1 ] [ 2 ] بأنها سلسلة من التعليمات التي، كما هي مكتوبة، ستستمر إلى ما لا نهاية، ما لم يحدث تدخل خارجي، مثل إيقاف تشغيل الطاقة عبر مفتاح أو فصل قابس. وقد يكون ذلك مقصودًا.

لا توجد خوارزمية عامة لتحديد ما إذا كان برنامج الكمبيوتر يحتوي على حلقة لا نهائية أم لا؛ هذه هي مشكلة التوقف .

ملخص

الحلقة اللانهائية هي سلسلة من التعليمات في برنامج حاسوبي تتكرر بلا نهاية، إما لعدم وجود شرط إنهاء لها، أو لوجود شرط لا يمكن تحقيقه ، أو لوجود شرط يُعيد الحلقة إلى نقطة البداية. في أنظمة التشغيل القديمة التي تدعم تعدد المهام التعاوني ، كانت الحلقات اللانهائية تتسبب عادةً في توقف النظام عن الاستجابة. أما مع نموذج تعدد المهام الاستباقي السائد حاليًا، فتؤدي الحلقات اللانهائية عادةً إلى استهلاك البرنامج لكامل وقت المعالج المتاح، ولكن يمكن للمستخدم عادةً إيقافها. تُسمى حلقات الانتظار المشغول أحيانًا " حلقات لانهائية". تُعد الحلقات اللانهائية أحد الأسباب المحتملة لتوقف الحاسوب أو تجمده ؛ وتشمل الأسباب الأخرى: التذبذب المفرط ، والتعطل ، وانتهاكات الوصول .

التكرار المقصود مقابل التكرار غير المقصود

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

التكرار المتعمد

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

تتطلب الحواسيب التفاعلية الحديثة مراقبة مستمرة لمدخلات المستخدم أو نشاط الجهاز، لذا توجد، على مستوى أساسي، حلقة معالجة لا نهائية تستمر حتى إيقاف تشغيل الجهاز أو إعادة ضبطه. في حاسوب توجيه أبولو ، على سبيل المثال، كانت هذه الحلقة الخارجية مُضمنة في برنامج Exec، [ 5 ] وإذا لم يكن لدى الحاسوب أي عمل آخر يقوم به، فإنه يُشغّل مهمة وهمية تُطفئ ببساطة مؤشر "نشاط الحاسوب".

تعدد الخيوط

في البرامج متعددة الخيوط، يمكن لبعض الخيوط أن تعمل داخل حلقات لا نهائية دون أن يتسبب ذلك في توقف البرنامج بأكمله داخل حلقة لا نهائية. إذا توقف الخيط الرئيسي، تتوقف جميع خيوط العملية قسرًا، وبالتالي ينتهي التنفيذ وتنتهي العملية/البرنامج. يمكن للخيوط الموجودة داخل الحلقات اللانهائية القيام بمهام "صيانة" أو البقاء في حالة انتظار (من مقبس/طابور) واستئناف التنفيذ عند تلقي أي مدخلات.

التكرار غير المقصود

شاشة الموت الزرقاء على نظام التشغيل ويندوز إكس بي . " علق برنامج تشغيل الجهاز في حلقة لا نهائية."

في أغلب الأحيان، يُستخدم هذا المصطلح لوصف الحالات التي لا تكون فيها هذه هي النتيجة المقصودة؛ أي عندما يكون هذا خطأً برمجيًا . [ 6 ] تُعد هذه الأخطاء شائعة بين المبرمجين المبتدئين، ولكن يمكن أن يرتكبها المبرمجون ذوو الخبرة أيضًا، لأن أسبابها قد تكون دقيقة للغاية.

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

على الرغم من أنه يمكن العثور على معظم الحلقات اللانهائية من خلال الفحص الدقيق للكود، إلا أنه لا توجد طريقة عامة لتحديد ما إذا كان برنامج معين سيتوقف أم سيستمر في العمل إلى الأبد؛ هذه هي مشكلة عدم قابلية الحسم في مشكلة التوقف . [ 7 ]

مقاطعة

طالما أن النظام يستجيب، يمكن غالبًا مقاطعة الحلقات اللانهائية بإرسال إشارة إلى العملية (مثل SIGINT في أنظمة يونكس)، أو مقاطعة إلى المعالج، مما يؤدي إلى إنهاء العملية الحالية. يمكن القيام بذلك من خلال مدير المهام ، أو في طرفية باستخدام الأمر Ctrl+C ، [ 8 ] أو باستخدام الأمر kill أو استدعاء النظام . مع ذلك، لا تنجح هذه الطريقة دائمًا، فقد لا تستجيب العملية للإشارات أو قد يكون المعالج في حالة غير قابلة للمقاطعة، كما هو الحال في خطأ غيبوبة Cyrix (الناجم عن تداخل التعليمات غير القابلة للمقاطعة في مسار التعليمات ). في بعض الحالات، قد تنجح إشارات أخرى مثل SIGKILL ، لأنها لا تتطلب استجابة العملية، بينما في حالات أخرى، لا يمكن إنهاء الحلقة إلا بإيقاف تشغيل النظام.

الدعم اللغوي

يمكن تنفيذ الحلقات اللانهائية باستخدام بنيات تحكم تدفق متنوعة . في البرمجة غير المهيكلة، يكون ذلك عادةً بالعودة إلى الأعلى ( goto )، بينما في البرمجة المهيكلة، يكون ذلك بحلقة غير محددة ( حلقة while ) مُعدّة بحيث لا تنتهي أبدًا، إما بحذف الشرط أو بتعيينه صراحةً إلى صحيح while (true) ....

تحتوي بعض اللغات على بنى خاصة للحلقات اللانهائية، وذلك عادةً عن طريق حذف الشرط من الحلقة غير المحددة. ومن الأمثلة على ذلك لغات مثل Ada و Fortran وloop ... end loop Go و Ruby و Rust .DO ... END DOfor { ... }loop do ... endloop { ... }

يمكن أيضاً إنشاء حلقات لا نهائية باستخدام الاستدعاء الذاتي . وتسمى هذه العملية بالاستدعاء الذاتي اللانهائي .

أمثلة على الحلقات اللانهائية المتعمدة

هذه حلقة ستطبع عبارة "حلقة لا نهائية" دون توقف، بلغة C :

#include <stdio.h>int main () { for (;;) { printf ( "حلقة لا نهائية \n " ); } return 0 ; }

إن شكل for (;;)الحلقة اللانهائية تقليدي، ويظهر في المرجع القياسي للغة البرمجة C ، وغالبًا ما يُنطق "forever". [ 10 ] ومع ذلك، فإن وجوده لا يضمن حلقة لانهائية حيث يمكن إنهاء الحلقة عن طريق كسرها باستخدام `break` break، أو إرجاعها باستخدام `return` return، أو القفز باستخدام `jump` goto.

في لغة C واللغات المشتقة منها، ربما يتم التعبير عن الحلقة اللانهائية بشكل أكثر حداثة على النحو التالي while (true):

#include <stdio.h>int main () { while ( true ) { printf ( "حلقة لا نهائية \n " ); } return 0 ; }

في اللغات المنحدرة من لغة C، مثل C++ و Java و C# ، من الأنسب استخدام while (true).

مثال مشابه في لغة BASIC في حقبة الثمانينيات :

10 اطبع "حلقة لا نهائية" 20 انتقل إلى 10

مثال مشابه في ملفات الدفعات المتوافقة مع نظام التشغيل MS-DOS :

: صدى حلقة لا نهائية انتقل إلى : أ

لا تنتهي حلقة while أبدًا لأن شرطها صحيح دائمًا.

في فيلم بورن مرة أخرى : شل

for (( ;; )) ; do echo "Infinite Loop" done

أمثلة على الحلقات اللانهائية غير المقصودة

الأخطاء الرياضية

إليك مثال واحد على حلقة لا نهائية في لغة فيجوال بيسك :

dim x as integer do while x < 5 x = 1 x = x + 1 loop

يُؤدي هذا إلى حالة لن تتجاوز فيها قيمة المتغير 5 أبدًا، حيث تُسند إليه القيمة 1 xفي بداية حلقة التكرار (بغض النظر عن أي قيمة سابقة) قبل أن تُغيّر إلى +1. وبالتالي، ستُؤدي الحلقة دائمًا إلى النتيجة 2 ولن تتوقف. يُمكن حل هذه المشكلة بنقل التعليمة خارج الحلقة بحيث تُعيّن قيمتها الابتدائية مرة واحدة فقط.xxxx = 1

في بعض لغات البرمجة، قد يؤدي التباس المبرمجين حول الرموز الرياضية إلى حلقة تكرار لا نهائية غير مقصودة. على سبيل المثال، إليك مقتطف برمجي بلغة C :

#include <stdio.h>int main ( void ) { int a = 0 ; while ( a < 10 ) { printf ( "%d \n " , a ); if ( a = 5 ) { printf ( "a equals 5! \n " ); } ++ a ; } return 0 ; }

الناتج المتوقع هو الأرقام من 0 إلى 9، مع عبارة "a يساوي 5!" بين 5 و6. مع ذلك، في السطر " if (a = 5)" أعلاه، تم الخلط بين عامل الإسناد (=) وعامل المساواة (==). بدلاً من ذلك، سيتم إسناد القيمة 5 إلى المتغير aفي هذه المرحلة من البرنامج. وبالتالي، aلن يتمكن المتغير من الانتقال إلى 10، ولن تنتهي هذه الحلقة.

أخطاء التقريب

مخرجات لغة C على معالج AMD Turion :
x = 0.10000000149011611938
x = 0.20000000298023223877
x = 0.30000001192092895508
x = 0.40000000596046447754
x = 0.50000000000000000000
x = 0.60000002384185791016
x = 0.70000004768371582031
x = 0.80000007152557373047
x = 0.90000009536743164062
x = 1.00000011920928955078
x = 1.10000014305114746094
x = 1.20000016689300537109
...

قد يتسبب السلوك غير المتوقع في تقييم شرط الإنهاء في هذه المشكلة أيضًا. إليك مثال بلغة C :

float x = 0.1 ; while ( x != 1.1 ) { printf ( "x = %22.20f \n " , x ); x += 0.1 ; }

في بعض الأنظمة، ستُنفَّذ هذه الحلقة عشر مرات كما هو متوقع، بينما في أنظمة أخرى لن تنتهي أبدًا. تكمن المشكلة في أن شرط إنهاء الحلقة يختبر التساوي التام بين قيمتين عشريتين ، وطريقة تمثيل القيم العشرية في العديد من الحواسيب تجعل هذا الاختبار يفشل، لأنها لا تستطيع تمثيل القيمة 0.1 بدقة، مما يُدخل أخطاء تقريب في كل زيادة (انظر المربع).(x != 1.1)

يمكن أن يحدث الشيء نفسه في لغة بايثون :

x : float = 0.1 while x != 1 : print ( x ) x += 0.1

نظرًا لاحتمالية فشل اختبارات المساواة أو عدم المساواة بشكل غير متوقع، يُفضّل استخدام اختبارات أكبر من أو أصغر من عند التعامل مع القيم العشرية. على سبيل المثال، بدلًا من اختبار ما إذا كانت القيمة xتساوي 1.1، يمكن اختبار ما إذا كانت تساوي 1 (x <= 1.0)أو 1 أو (x < 1.1)1، حيث سيؤدي أيٌّ من هذين الاختبارين إلى إنهاء الحلقة بعد عدد محدود من التكرارات. ويمكن أيضًا معالجة هذا المثال باستخدام عدد صحيح كمؤشر للحلقة ، لحساب عدد التكرارات التي تم تنفيذها.

تتكرر مشكلة مماثلة في التحليل العددي : فلكي يتم حساب نتيجة معينة، يُراد إجراء عملية تكرارية حتى يصبح الخطأ أصغر من قيمة التسامح المحددة. إلا أنه بسبب أخطاء التقريب أثناء التكرار، لا يمكن الوصول إلى قيمة التسامح المحددة، مما يؤدي إلى حلقة لا نهائية.

حلقات متعددة الأطراف

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

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

الحلقات شبه اللانهائية

الحلقة شبه اللانهائية هي حلقة تبدو لانهائية ولكنها في الحقيقة مجرد حلقة طويلة جدًا.

شرط إنهاء مستحيل

مثال على حلقة for في لغة C :

for ( unsigned int i = 1 ; i != 0 ; i ++ ) {}

يبدو أن هذا سيستمر إلى ما لا نهاية، لكن في الواقع iستصل قيمة المتغير في النهاية إلى الحد الأقصى للقيمة التي يمكن تخزينها في المتغير unsigned int، وإضافة 1 إلى هذا العدد سيؤدي إلى تجاوز الحد الأقصى، مما يتسبب في حدوث تجاوز في عدد صحيح ، وبالتالي توقف الحلقة. يعتمد الحد الفعلي للمتغير iعلى تفاصيل النظام والمترجم المستخدم. مع العمليات الحسابية ذات الدقة العشوائية ، ستستمر هذه الحلقة حتى لا تستطيع ذاكرة الحاسوب استيعاب المتغير i. إذا iكان المتغير عددًا صحيحًا مُوَقَّعًا، بدلًا من عدد صحيح غير مُوَقَّع، فسيكون التجاوز غير مُعَرَّف .

انظر أيضاً

مراجع

  1. "تعريف قاموس الحلقة اللانهائية" . مؤرشف من الأصل بتاريخ 2020-08-01 . تم الاطلاع عليه بتاريخ 2020-01-22 .
  2. "ما هي الحلقة اللانهائية (الحلقة التي لا نهاية لها)؟" . مؤرشف من الأصل بتاريخ 15 يوليو 2019. تم الاطلاع عليه بتاريخ 22 يناير 2020 .
  3. "الرموز والأنماط: طبيعة ثقافة الأفلام الوثائقية" . مجلة فلو . نوفمبر 2014. مؤرشف من الأصل في 1 أغسطس 2020. تم الاطلاع عليه في 23 يناير 2020. الحلقة اللانهائية هي حلقة تفتقر إلى شرط خروج .
  4. يُعرف أيضًا باسم تعدد المهام غير الاستباقي: "تعدد المهام غير الاستباقي" . مجلة الكمبيوتر الشخصي . مؤرشف من الأصل في 26 يوليو 2019. تم الاطلاع عليه في 7 فبراير 2024 .
  5. ديفيد هوغ (سبتمبر 1976). "تاريخ التوجيه والملاحة والتحكم على متن مركبات أبولو" (ملف PDF) . مختبر تشارلز ستارك دريبر. مؤرشف (ملف PDF) من الأصل بتاريخ 5 نوفمبر 2016. تم الاطلاع عليه بتاريخ 23 يناير 2020 .
  6. "إجابات كلمات متقاطعة نيويورك تايمز" . ١٣ أكتوبر ٢٠١٣. مؤرشف من الأصل في ٢ أغسطس ٢٠٢٠. تم الاسترجاع في ٢٢ يناير ٢٠٢٠. الحوسبة .. عيب .. الذي .. للتكرار
  7. "مشكلة التوقف في نظرية الحوسبة" . 3 أكتوبر 2018. مؤرشف من الأصل في 9 أغسطس 2020. تم الاطلاع عليه في 22 يناير 2020 .
  8. "استغلال ثغرة تجاوز سعة المخزن المؤقت في برنامج التحكم عن بُعد DameWare" . ١٩ ديسمبر ٢٠٠٣. مؤرشف من الأصل في ٢٤ يوليو ٢٠٢٠. تم الاطلاع عليه في ٢٢ يناير ٢٠٢٠. بمجرد إغلاق موجه الأوامر باستخدام اختصار لوحة المفاتيح Ctrl+C ...
  9. برمجة آدا: التحكم: حلقة لا نهائية
  10. "حلقة لا نهائية في لغة C/C++" . مؤرشف من الأصل بتاريخ 2016-08-03.