عندما تكون كل ميلي ثانية مهمة: لماذا نحتاج إلى نوم دقيق في C++
\n\nتخيل أنك تكتب لعبة حيث يهاجم الأعداء كل 500 مللي ثانية. أو تقوم بتطوير وحدة تحكم صناعية تستشعر جهاز استشعار بدقة كل 10 مللي ثانية. أو ببساطة تريد إنشاء رسوم متحركة للتحميل مع ظهور النص بسلاسة. في كل هذه الحالات، ستحتاج إلى الأمر: sleep for milliseconds.
قد يبدو الأمر بسيطًا - "إيقاف" تيار لفترة زمنية محددة؟ لكن في C++، على عكس Python أو JavaScript، لا توجد دالة واحدة مدمجة "انتظر N مللي ثانية". بتعبير أدق، توجد، لكنها تختلف باختلاف أنظمة التشغيل والمعايير. وهناك أيضًا عثرات: الدقة، قابلية النقل، التأثير على الأداء.
\n\nفي هذه المقالة، سنستعرض جميع الطرق لعمل تأخير في C++ بالميلي ثانية: من الطرق الكلاسيكية Sleep() و usleep() إلى الطريقة الحديثة std::this_thread::sleep_for(). ستحصل على أمثلة جاهزة للكود، وستعرف أي طريقة تختار لمهمتك، وستتعلم تجنب الأخطاء الشائعة.
الطريقة القياسية: std::this_thread::sleep_for (C++11 وما بعده)
\n\nبدءًا من معيار C++11، ظهرت مكتبة <chrono> وإمكانية تأخير التيار بشكل قابل للنقل. هذه هي الطريقة الأصح والأكثر توصية لكود C++ الحديث.
كيف يعمل
\n\nتأخذ الدالة std::this_thread::sleep_for() فاصل زمني، محدد باستخدام std::chrono::duration. يمكنك ببساطة تحديد عدد الميلي ثانية، وسيتم "إيقاف" التيار لهذه المدة.
مثال 1: تأخير أساسي لمدة 500 مللي ثانية
\n\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n std::cout << "نبدأ العد...\\n";\n \n // تأخير لمدة 500 مللي ثانية\n std::this_thread::sleep_for(std::chrono::milliseconds(500));\n \n std::cout << "مرت نصف ثانية!\\n";\n return 0;\n}\n\nسيعمل هذا الكود على Windows و Linux و macOS وأي منصة أخرى مع مترجم C++11/14/17/20. لا حاجة لـ #ifdef، ولا لاستدعاءات النظام.
\n\nمثال 2: تأخير بمتغير
\n\nإذا كنت بحاجة إلى تحديد الوقت ديناميكيًا:
\n\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nvoid process_with_delay(int delay_ms) {\n std::cout << "معالجة بتأخير " << delay_ms << " مللي ثانية...\\n";\n std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));\n std::cout << "تم!\\n";\n}\n\nint main() {\n process_with_delay(200);\n process_with_delay(1000);\n return 0;\n}\n\nهام: دقة sleep_for
\n\nلا تضمن الدالة sleep_for() دقة مطلقة حتى الميكروثانية. قد يكون وقت الاستيقاظ الفعلي أطول قليلاً (ببضع مللي ثانية) بسبب جدولة نظام التشغيل. بالنسبة لمعظم المهام (الرسوم المتحركة، المهلات، استشعار أجهزة الاستشعار) هذا كافٍ. إذا كنت بحاجة إلى دقة ميكروثانية - راجع قسم "عندما تكون الدقة حرجة".
الطريقة الكلاسيكية: Sleep() لنظام Windows
\n\nإذا كنت تكتب كودًا لنظام Windows فقط (على سبيل المثال، مشروع قديم على Visual Studio)، يمكنك استخدام الدالة Sleep() من API Windows. إنها "تنام" بدقة بالميلي ثانية.
مثال 3: تأخير لمدة ثانية واحدة تحت Windows
\n\n#include <iostream>\n#include <windows.h> // يجب تضمينه\n\nint main() {\n std::cout << "ننتظر ثانية واحدة (Windows)...\\n";\n Sleep(1000); // الوسيط بالميلي ثانية\n std::cout << "استيقظنا!\\n";\n return 0;\n}\n\nالعيوب:
\n- \n
- لا يعمل على Linux/macOS. \n
- يتطلب تضمين
<windows.h>، مما قد يسبب تعارضات في الأسماء. \n