سؤال

لدي فئة A وقائمة بالأشياء. يحتوي على وظيفة F التي يجب تنفيذها كل ثانية x (للمثيل الأول كل ثانية واحدة، مثيل الثواني كل 5 ثوان، إلخ). لدي فئة مجدولة مسؤولة عن تنفيذ الوظائف في الوقت الصحيح. ما اعتقدت القيام به هو إنشاء فئة جديدة، اتيم، التي ستحمل PTR بمثيل، ويجب تنفيذ الوقت A: F. سيعقد المجدول قائمة انتظار أولوية دقيقة من ATIME.

  1. هل تعتقد أنه التنفيذ الصحيح؟
  2. يجب أن يكون عطرا فئة متداخلة من الجدولة؟
هل كانت مفيدة؟

المحلول

من ما تصفه، يبدو أنه يمكن أن يعمل :-)

فئة IMHO ATime ينتمي إلى المجدول أكثر من A. من الضروري أن يقوم المجدول بإجراء وظيفته، وليس هناك حاجة ل A. في الواقع، لا يحتاج ذلك (وبقية العالم) إلى عدم معرفة وجوده - لذا سيكون فئة متداخلة خاصة من المجدول مناسبة بالنسبة لي.

نصائح أخرى

قد يكون هذا متقدم قليلا جدا، ولكن هنا يذهب ...

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

فيما يلي بعض رمز العينة الذي يوضح كيف يمكن استخدام مرافق دفعة هذه في قضيتك:

#include <ctime>
#include <queue>
#include <boost/function.hpp>
#include <boost/bind.hpp>

struct Foo
{
    void onScheduler(time_t time) {/*...*/}
};

struct Bar
{
    void onScheduler(time_t time) {/*...*/}
};

typedef boost::function<void (time_t)> SchedulerHandler;

struct SchedulerEvent
{
    bool operator<(const SchedulerEvent& rhs) const {return when < rhs.when;}

    SchedulerHandler handler;
    time_t when;
};

class Scheduler
{
public:
    void schedule(SchedulerHandler handler, time_t when)
    {
        SchedulerEvent event = {handler, when};
        queue_.push(event);
    }

private:
    std::priority_queue<SchedulerEvent> queue_;
    void onNextEvent()
    {
        const SchedulerEvent& next = queue_.top();
        next.handler(next.when);
        queue_.pop();
    }
};

int main()
{
    Scheduler s;
    Foo f1, f2;
    Bar b1, b2;

    time_t now = time(0);
    s.schedule(boost::bind(&Foo::onScheduler, &f1, _1), now + 1);
    s.schedule(boost::bind(&Foo::onScheduler, &f2, _1), now + 2);
    s.schedule(boost::bind(&Bar::onScheduler, &b1, _1), now + 3);
    s.schedule(boost::bind(&Bar::onScheduler, &b2, _1), now + 4);

    // Do scheduling...

    return 0;
}

لاحظ أن Scheduler لا يعرف شيئا عن Foo & Bar, والعكس صحيح. الجميع Scheduler حقا يريد هو Functor "رد الاتصال" الذي يطابق التوقيع المحدد بواسطة SchedulerHandler.

إذا كنت بحاجة إلى SchedulerEvent لتكون الإطلالة، تصبح الأمور معقدة بعض الشيء بسبب boost::function الكائنات غير قابلة للمقارنة. للتحصل حول هذا، ستحتاج إلى إرجاع نوعا ما من رمز "الاتصال" عند تسجيل الأحداث. هذا هو في الأساس ما boost.signal يفعل.

أتمنى أن يساعدك هذا.

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

فيما يتعلق بالجزء الثاني (والسؤال الموجود في العنوان)، فإن IMO هو مسألة ذوق تماما. هل يمكن أن تختار أيضا تقليل الفوضى في تعريف فئة المجدول، ووضع ATIME في شبكة شراب نسوية مع اسم تحذير (مثل detail) للحفاظ على الناس من استخدامها. بعد كل شيء، إذا كانت مفيدة فقط للجدولة، فلا نحتاج كثيرا إلى إخفاءها كثيرا - لا يريد أحد استخدامه على أي حال.

ربما قد يكون مختلفا في C ++ 0x (أعتقد أنني سمعت بعض الشائعات كيف ستغير قواعد إمكانية الوصول بين فئة متداخلة وأداء، أو نحو ذلك، في هذه الحالة قد تكون التعشيش أكثر جديرة بالاهتمام).

بالنسبة إلى Generity، قد ترغب أيضا في الاستفادة من القوالب، وربما في نهاية المطاف Scheduler<A> (باستخدام أ. TimedOperation<A>) (أو عدد لا يحصى من التحسينات المحتملة / التعميمات من ذلك)؟

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