Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Fynjisx от Ноябрь 21, 2018, 13:10



Название: Удаление аггрегируемого объекта в другом потоке
Отправлено: Fynjisx от Ноябрь 21, 2018, 13:10
Привет всем! Вопрос такой:
Есть класс, в котором один из агрегируемых объектов после создания класса переносится в другой поток!
Если я разрушаю объект класса верхнего уровня, будет ли удаляться агрегируемый объект, который уже в другом потоке или ему надо явно засылать deletelater в деструкторе класса верхнего уровня???


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 21, 2018, 13:35
Если ему парент назначен, то в отличный от родительского потока он не переместится.
А если не назначен, то кто его удалит, кроме программиста?


Название: Re: Удаление аггрегируемого объекта в друго&#
Отправлено: Fynjisx от Ноябрь 21, 2018, 15:49
Если ему парент назначен, то в отличный от родительского потока он не переместится.
А если не назначен, то кто его удалит, кроме программиста?
Парент не назначен. Я думал, все аггрегируемые объекты уничтожаются автоматически при удалении класса контейнера.
Так, как грамотно его удалить? В деструкторе класса контейнера deleteLater() сделать?


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: Fregloin от Ноябрь 21, 2018, 16:26
Ответ - удалять вручную в другом потоке


Название: Re: Удаление аггрегируемого объекта в друго&#
Отправлено: Igors от Ноябрь 21, 2018, 16:30
Я думал, все аггрегируемые объекты уничтожаются автоматически при удалении класса контейнера.
Правильно думали, так и есть. Опасность что удалится объект который сейчас используется другой ниткой - проблема типовая, с "переносом" (moveToThread) она не связана. Какое-то общего/универсального решения нет. Самое простое - не удалять объект пока не завершится нитка использующая хотя бы один из его членов. Ну или связываться с QSharedPointer.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 21, 2018, 17:32
Можно сконнектить сигнал destroyed() класса контейнера с методом deleteLater() вложенного класса.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: Igors от Ноябрь 21, 2018, 17:49
Можно сконнектить сигнал destroyed() класса контейнера с методом deleteLater() вложенного класса.
Это не поможет если удаляется объект "верхнего уровня", все его члены будут разрушены. 


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 21, 2018, 19:16
Можно сконнектить сигнал destroyed() класса контейнера с методом deleteLater() вложенного класса.
Это не поможет если удаляется объект "верхнего уровня", все его члены будут разрушены. 
С чего это, если парента никто не назначал?

Код:
Container::Container(QObject *parent)
    : QObject(parent)
    , m_workersThread(new QThread)

{
    m_workersThread->start();
    QObject::connect(m_workersThread, &QThread::started,
                     this, &Container::run);
    QObject::connect(this, &Container::ready,
                     this, &QObject::deleteLater);
}

void Container::run()
{
    for (int i = 0; i < 3; ++i)
    {
        Worker* worker = new Worker;
        QObject::connect(this, &QObject::destroyed,
                         worker, &QObject::deleteLater);
        worker->moveToThread(m_workersThread);
        m_workers.push_back(worker);
    }
    emit ready();
}

Worker::Worker(QObject *parent)
    : QObject(parent)
{
}

Worker::~Worker()
{
    qDebug() << "destroy";
}

выводит 3 раза  "destroy"


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: Igors от Ноябрь 22, 2018, 07:22
С чего это, если парента никто не назначал?
Причем тут парент? Насколько я понял, у ТС такая ситуевина
Код
C++ (Qt)
class MyClass {
...
 SomeClass m_data;   // этот член переносится в др поток
};


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 22, 2018, 09:37
С чего это, если парента никто не назначал?
Причем тут парент? Насколько я понял, у ТС такая ситуевина
Код
C++ (Qt)
class MyClass {
...
 SomeClass m_data;   // этот член переносится в др поток
};
Если человек задался вопросом про deleteLater() то логично было предположить, что он работает через указатели. Что я собственно и сделал.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: ViTech от Ноябрь 22, 2018, 11:32
Причем тут парент? Насколько я понял, у ТС такая ситуевина
...

Если человек задался вопросом про deleteLater() то логично было предположить, что он работает через указатели. Что я собственно и сделал.

Я делаю ставку, что там должен быть QPointer, кто больше? :) Может лучше пусть ТС сам расскажет, что именно у него там находится, какая агрегация и зачем потоки.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: Авварон от Ноябрь 22, 2018, 16:54
Может лучше пусть ТС сам расскажет, что именно у него там находится, какая агрегация и зачем потоки.

Тссс, телепаты вышли из отпуска.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: sergek от Ноябрь 22, 2018, 17:00
Коллеги, может просто рассмотрим варианты указателя и объекта? Не знаю, зачем это нужно, но ну его, этого ТС, просто интересно.  ;)


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 22, 2018, 17:07
Коллеги, может просто рассмотрим варианты указателя и объекта? Не знаю, зачем это нужно, но ну его, этого ТС, просто интересно.  ;)
Так уже все рассмотрели, ну кроме умных указателей.
ТСу есть из чего выбирать.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: sergek от Ноябрь 22, 2018, 17:52
Так уже все рассмотрели, ну кроме умных указателей.
Да? Может, я зря сомневаюсь, но если указатели, и послан сигнал на deleteLate объекта в другом потоке, то нужно ли контейнеру дожидаться, пока объект уничтожится?


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: RedDog от Ноябрь 22, 2018, 18:25
Так уже все рассмотрели, ну кроме умных указателей.
Да? Может, я зря сомневаюсь, но если указатели, и послан сигнал на deleteLate объекта в другом потоке, то нужно ли контейнеру дожидаться, пока объект уничтожится?
ТЗ слишком куцее, как у ТС.


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: Igors от Ноябрь 23, 2018, 10:59
Коллеги, может просто рассмотрим варианты указателя и объекта? Не знаю, зачем это нужно, но ну его, этого ТС, просто интересно.  ;)
Если имеется ввиду
Код
C++ (Qt)
class MyClass {
...
 SomeClass * m_dataPtr;  
};
то это никакой не агрегат, тут вообще неизвестно кто ответит за удаление m_dataPtr.

Да? Может, я зря сомневаюсь, но если указатели, и послан сигнал на deleteLate объекта в другом потоке, то нужно ли контейнеру дожидаться, пока объект уничтожится?
А как должно выглядеть такое ожидание? Не вижу разумных/естественных вариантов.

Постановка выглядит нездоровой. Зачем владение (и ответственность за удаление) иметь в др нитке?


Название: Re: Удаление аггрегируемого объекта в другом потоке
Отправлено: sergek от Ноябрь 23, 2018, 12:33
А как должно выглядеть такое ожидание? Не вижу разумных/естественных вариантов.

Постановка выглядит нездоровой. Зачем владение (и ответственность за удаление) иметь в др нитке?
Чисто академический интерес.