ما هي أفضل طريقة للخروج من حلقة بعد وقت انقضت 30ms في C ++

StackOverflow https://stackoverflow.com/questions/946167

  •  09-09-2019
  •  | 
  •  

سؤال

ما هي أفضل طريقة للخروج من حلقة أقرب إلى 30ms قدر الإمكان في C ++. دفعة الاقتراع: Microsec_Clock؟ الاقتراع قرين؟ شيء آخر؟

شيء مثل:

A = now;
for (blah; blah; blah) {
    Blah();
    if (now - A > 30000)
         break;
}

يجب أن تعمل على Linux و OS X و Windows.

الحسابات في الحلقة هي لتحديث المحاكاة. كل 30 مللي ثانية، أود تحديث العرض.

هل كانت مفيدة؟

المحلول

مثال Snippet Snippet في هذا الرابط بشكل كبير يفعل ما تريد:

http://www.cplusplus.com/Reference/Clibrary/ctime/clock/

تكييفها من مثالهم:

void runwait ( int seconds )
{
   clock_t endwait;
   endwait = clock () + seconds * CLOCKS_PER_SEC ;
   while (clock() < endwait)
   {
      /* Do stuff while waiting */
   }
}

نصائح أخرى

الحسابات في الحلقة هي لتحديث المحاكاة. كل 30 مللي ثانية، أود تحديث العرض.

هل فكرت في استخدام المواضيع؟ يبدو أن ما تصفه مثالا مثاليا لماذا يجب عليك استخدام مؤشرات الترابط بدلا من أجهزة توقيت.

يحتفظ مؤشر ترابط العمليات الرئيسي بعناية UI، ولديه مجموعة Qtimer إلى 30 مللي ثانية لتحديثه. يقلق أ qmutex. للحصول على الوصول إلى البيانات، يقوم بتنفيذ التحديث، وينطلق Mutex.

الموضوع الثاني (انظر qthread.) هل المحاكاة. بالنسبة لكل دورة، يقوم بإغلاق QMUTEX، هل الحسابات وتطلق MUTEX عند وجود البيانات في حالة مستقرة (مناسبة لتحديث UI).

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

في حين أن هذا لا يجيب على السؤال، فقد يعطي نظرة أخرى على الحل. ماذا عن وضع رمز المحاكاة وواجهة المستخدم في مواضيع مختلفة؟ إذا كنت تستخدم QT، فيمكن تحقيق التحديث الدوري باستخدام مؤقت أو حتى qthread :: msleep (). وبعد يمكنك تكييف مثال ماندلبروت الخيوط لتناسب حاجتك.

إذا كنت بحاجة إلى القيام بالعمل حتى ينقض وقت معين، ثم إجابة docflabby هو البداية. ومع ذلك، إذا كنت بحاجة فقط إلى الانتظار، فلا تفعل شيئا، حتى ينقض وقت محدد، ثم يجب عليك استخدام usleep()

إجابة قصيرة هي: لا يمكنك بشكل عام، ولكن يمكنك إذا كنت تعمل على نظام التشغيل الأيمن أو على الأجهزة المناسبة.

يمكنك الاقتران من 30ms على جميع نظام التشغيل باستخدام مكالمة تجميع على أنقات Intel وشيء آخر على بنية أخرى. سأحفر المرجع وتحرير الإجابة لتضمين التعليمات البرمجية عندما أجدها.

المشكلة هي خوارزمية تقطيع الوقت وكيف بالقرب من نهاية وقتك شريحة أنت على نظام التشغيل متعدد المهام.

في بعض الوقت في الوقت الفعلي، هناك مكالمة نظام في مكتبة النظام، يمكنك القيام به، لكنني لست متأكدا من أن هذه المكالمة ستكون.

تحرير: لول! شخص ما نشر بالفعل مقتطفا مشاجئا على ذلك: وظيفة الموقت لتوفير الوقت في ثواني النانو باستخدام C ++

حصلت VONC على التعليق مع رمز مجموعة CPU Timer Admany في ذلك.

وفقا لسؤالك، كل 30 مللي ثانية ترغب في تحديث العرض. كتبت تطبيقا مشابها بمجرد أن يقوم هذا الجهاز بتحقيق كل 500ms لأشياء مشابهة. في حين أن هذا لا يجيب على سؤالك مباشرة، لدي المتابعات التالية:

  • هل أنت متأكد من أن BLAH ()، لتحديث Viewport، يمكن أن تنفذ في أقل من 30 مللي ثانية في كل مثيل؟
  • يبدو أكثر مثل الجري BLAH () سيتم القيام به بشكل أفضل من اتصال توقيت.
  • من الصعب جدا العثور على كائن مؤقت مكتبة سيدفع فاصل زمني 30ms للقيام بتحديثات في إطار رسومي. على نظام التشغيل Windows XP، وجدت أن مؤقت واجهة برمجة تطبيقات Win32 القياسية التي تدفع رسائل النافذة عند انتهاء صلاحية الفاصل الزمني للموقت، حتى على 2 جيجا هرتز P4، لا يمكن أن تقوم بالتحديثات بأي أسرع من الفاصل الزمني 300ms، بغض النظر عن مدى تحديد الفاصل الزمني للتوقيت الموقت. في حين أن هناك أجهزة توقيت عالية الأداء متوفرة في واجهة برمجة تطبيقات Win32، فإنها لديها العديد من القيود، وهي أنه لا يمكنك القيام بأي IPC (مثل تحديث الحاجيات UI) في حلقة مثل تلك التي ذكرتها أعلاه.
  • في الأساس، يجب أن تخطط للتخطيط بعناية فائقة كيف تريد حدوث تحديثات. قد تحتاج إلى استخدام المواضيع، وإلقاء نظرة على الطريقة التي تريد تحديث العرض.

مجرد بعض الأشياء للتفكير. اشتعلتني مفاجأة عندما عملت في مشروعي. إذا كنت تعتقد أن هذه الأشياء من خلالها بالفعل، يرجى تجاهل إجابتي: 0).

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

انظر QueryPerformancounter و QueryPerformanceFrequency

إذا كنت تستخدم QT، فإليك طريقة بسيطة للقيام بذلك:

QTimer* t = new QTimer( parent ) ;
t->setInterval( 30 ) ; // in msec
t->setSingleShot( false ) ;
connect( t, SIGNAL( timeout() ), viewPort, SLOT( redraw() ) ) ;

ستحتاج إلى تحديد viewPort و redraw(). وبعد ثم ابدأ المؤقت t->start().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top