ما هو تأثير تغيير وقت النظام على خيوط النوم؟

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

  •  06-07-2019
  •  | 
  •  

سؤال

إذا ألقيت نظرة على clock_gettime () الوظيفة ، التي تتوفر في جميع BSDs ويتم تعريفها فعليًا كجزء من معيار POSIX ، ترى أن هناك دعمًا لثلاثة أنواع على الأقل من الساعات (العديد من الأنظمة تدعم أكثر من هذه الساعات ، ولكن في الواقع يتطلب معيار POSIX واحدًا إلى واحد إلى واحد كن حاضرًا ، كل الآخرين اختياريين):

  • clock_realtime - Posix يتطلب هذا ليكون حاضرا. هذه هي ساعة وقت الجدار.

  • clock_monotonic - لا فكرة عما يعنيه هذا (وما تعنيه ثواني SI) ، لكنني أفهم أن هذه الساعة لن تقفز أبدًا إلى الوراء ، بل يمكن أن تزيد من القيمة الرتامية.

  • clock_uptime - أخفق في معرفة كيف يختلف هذا عن clock_monotonic (لا تقفز وقت التشغيل أيضًا إلى الخلف) ، لكنني على الأقل أعلم أن هذه الساعة تبدأ من الصفر عندما تكون أحذية kernel (في حين أنه لم يتم تحديد ما هي القيمة الأولية على مدار الساعة _monotonic

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

الآن لدينا وظيفتان للنوم في نظام BSD. ينام() و nanosleep (). لست متأكدًا ، لكنني أتوقع تنفيذ Sleep () على رأس Nanosleep ، وبعد كل شيء يمكنني محاكاة Sleep () بسهولة باستخدام nanosleep () وضبط عدد الثواني فقط في الموعد النهائي للبنيس ، والحفاظ على النانوسية الصفر .

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

كل هذا عاقل تمامًا بالنسبة لي ... ولكن هناك سؤال واحد يزعجني دائمًا:

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

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

المحلول

على حد علمي ، عادة ما يتم تنفيذ وظائف النوم أشبه بمقاومة انخفاض. أنت تقول "النوم لمدة 10 ثوان" ، والتي تترجم إلى "Sleep for 1000 Tills Ticks" في المجدول ، ثم في كل مرة يتحقق فيها المجدول في عمليات النوم ، فإنه يقلل من مقدار الوقت المتبقي.

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

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

نصائح أخرى

سيتم التحقق من الخيط على عداد داخلي يتم تعيينه على مدة النوم وليس إلى نقطة نهاية النوم. لا علاقة للعداد الداخلي المستخدم بوقت النظام الحالي ، وبالتالي لن يتأثر في حالة حدوث أي تغييرات في وقت النظام.

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