Дизайн пула потоков
От: Alu Россия  
Дата: 27.08.09 07:04
Оценка:
Добрый день.
Разрабатываю свой простой пул потоков. О существовании готовых профессиональных реализаций знаю. Цель — практически Just For Fun.
Дизайн хотелось бы иметь в стиле Qt::QThread и Java.
Первый вариант:
class IRunable
{
public:
    virtual void Run() = 0;
    virtual ~IRunable();
};

void Start(IRunable* _pcRunable); // < запускает метод Run() _pcRunable в отдельном потоке.

Т.е. пользователь пула потоков просто реализует интерфейс IRunable, переопределённый метод Run() будет запущен в отдельном потоке:
class CSomeRunable : public IRunable
{
    virtual void Run(); // < Код пользователя, запускаемый в отдельном потоке.
    void AdditionalMethod();
};

Вопрос: Как корректно освободить ресурсы CSomeRunable, ведь такой объект будет использоваться двумя нитями сразу: нитью создающей объект и нитью исполняющей метод CSomeRunable::Run()
int main()
{
    CSomeRunable* p = new CSomeRunable();
    Start(p); // < Запуск  CSomeRunable::Run() в отдельной нити.

    // ....

    p->AdditionalMethod();

    // ....

    delete p; /// Некорректно! Нет гарантии что объект не используется другой нитью.
    
    return 0;
}

Недостатки:
При таком дизайне нужен отдельный активный механизм, который будет отслеживать завершился ли дочерний поток и когда тот завершится — удалит объект. Что-то типа активного сборщика мусора.
Второй вариант:
class IRunable
{
public:
    virtual void Run() = 0;
    virtual IRunable* Сlone() = 0; // < Создаёт копию объекта
    virtual ~IRunable() ;
};

void Start(const IRunable& _rcRunable); // < Создаёт копию _rcRunable и запускает метод Run() копии в отдельном потоке.
                                        // По завершении Run(), копия удаляется.

Недостатки:
1. Пользователю прийдётся реализовывать метод Сlone(), что может быть непросто для сложных объектов, имеющих средства синхронизации.
2. Пользователь теряет связь с активным объектом. Т.е. копия объекта должна сама сообщить свой адрес, чтобы пользователь мог с ней взаимодействовать из создающей нити.

Третий вариант:
Использовать потоковозащищённые умные указатели.
Недостатки:
Прийдётся тащить их из сторонних библиотек.

Четвёртый вариант:
Отказаться от IRunable в пользу указателей на ф-ии.
Недостатки: необъектно и подедовски

Буду благодарен как за модификации моих вариантов, так и за принципиально новые, с другим дизайном.
Спасибо.
Настоящему индейцу завсегда везде ништяк!
pool threads multithreading
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.