Название: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 02:57 Подскажите как правильно работать с потоками.
Сейчас я работаю с потоками так в главном потоке создаю их через new в конце функции run потока вызываю deleteLater(). Но тогда valgrind в логах пишет Код: 1,284 (20 direct, 1,264 indirect) bytes in 1 blocks are definitely lost in loss record Если я использую умные указатели например так Код: m_FooThreadPtr = QSharedPointer<FooThread>(new FooThread); Ситуация не меняется Если я использую умные указатели так Код: m_FooThreadPtr = QSharedPointer<FooThread>(new FooThread, &QObject::deleteLater); Ситуация немного меняется, меньше байт теряется Вот полный текст сообщения в логах Код: ==3164== 894 (20 direct, 874 indirect) bytes in 1 blocks are definitely lost in loss record 241 of 267 но в логах программы появляются сообщения Код: QObject: shared QObject was deleted directly. The program is malformed and may crash. Вообще в отчете valgrind очень много таких сообщений Код: ==3164== 4,048 bytes in 22 blocks are possibly lost in loss record 262 of 267 Т.е. мои утечки из 292 блоков только 2(те которые из моих исходников). Если я правильно читаю логи. Название: Re: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 03:05 Не большое дополнение поток завершается нормально от него приходит сигнал finished
Название: Re: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 03:09 Параметры с которми запускал valgrind:
--leak-check=yes --leak-resolution=med Название: Re: Работа с потоками Отправлено: brankovic от Апрель 09, 2011, 12:53 как правильно не знаю, но как-то делал такое и оно работало:
Код
валгринд не ругался (но я с сапрессами гонял) Название: Re: Работа с потоками Отправлено: Igors от Апрель 09, 2011, 14:02 Сейчас я работаю с потоками так в главном потоке создаю их через new в конце функции run потока вызываю deleteLater(). Это не есть хорошо. т.к.- нужно быть уверенным что не случилось moveToThread (есть ли у Вас EventLoop в нитке - неизвестно) - сделав deleteLater и рассчитывая что главная (или др.) удалит, Вы не знаете "когда" - а это может случиться еще до выхода из текущей ф-ции, где Вы полагаете что объект еще валиден Лучше действовать "кто создал - тот и удалил" или просто удалять "сейчас" или использовать auto_ptr - но не deleteLater, оно здесь не подходит Название: Re: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 17:27 Ясно.
Еще вопрос Где нужно инициализировать(выделять память) члены класса потока непосредственно в run или можно в конструкторе класса потока? Название: Re: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 19:40 Прочитал статью http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ из соседнего топика и уменя появились еще вопросы.
Мне нужно в поток передать массив строк. Который формируется в гуи. Как мне его правильно передать? Я думаю нужно так Код: class Worker : public QObject Но тогда у меня вопрос сколько копий вектора будет в приложении? 2 или 3. Название: Re: Работа с потоками Отправлено: like-nix от Апрель 09, 2011, 19:50 Или может быть благодаря implicit sharing если я данные менять не буду то вообще 1 =)
Название: Re: Работа с потоками Отправлено: Akon от Апрель 09, 2011, 20:04 2brankovich:
только вот так: Код: ... В изначальном варианте (без wait) возможно удаление при использовании (ниже finished() юзается this). Цитировать Или может быть благодаря implicit sharing если я данные менять не буду то вообще 1 =) Да. И используй const ссылку при передаче (const QVector<QString> &vector). Название: Re: Работа с потоками Отправлено: brankovic от Апрель 09, 2011, 20:11 2brankovich: только вот так: Код: ... понятно, спасибо. А не может он сам себя удалить? Если сделать слот suicide () {delete this;}, то я так понимаю всё ещё хуже, а можно как-то правильно сделать, или обязятельно другой поток участвует? И ещё, из-за этого wait гуи подвиснут? Edit: посмотрел доки, похоже лучше использовать QThreadPool, он сам всё удаляет. Название: Re: Работа с потоками Отправлено: Akon от Апрель 09, 2011, 20:59 suicide () {delete this;}
ИМХО, не стоит такое использовать вообще. К примеру, есть стековый объект и ничто не мешает сделать вызов: Crazy crazy; crazy.suicide(); ;D Из-за wait ожидание должно быть мизерным, т.к. участок кода после finished() и возвращением в ОС небольшой (см. QThreadPrivate::finish(), если не ошибаюсь). А не может он сам себя удалить? Понимаю, хотите чего-то элегантного, типа new MyThread(parameters).start(); // task и работу сделает, и сам за собой все уберет и ссылок на него не надо :) Чтобы такое сделать нужно удалять перед самым возвратом в ОС (т.е. к this уже не будет обращений). Нужно падчить сорцы. |