crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Как на создавать потоков по количеству ядер, а потом завершить их?
RazrFalcon
  опции профиля:
сообщение 5.11.2011, 16:33
Сообщение #1


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Циклично создаются потоки:
for (int i = 0; i < list.count(); ++i) {
    MyThread *myTh = new MyThread();
    QThread *th = new QThread(this);
    connect(cleanerM,SIGNAL(done()),this,SLOT(cleaningFinished()));
    myTh->moveToThread(th);
    th->start();
}

Затем на cleaningFinished я вызываю:
QThread *th = qobject_cast<QThread *>(sender());
th->quit();

Это нормальное решение или есть более правильное?


И как можно завершить все потоки? ака кнопка "стоп".

Сообщение отредактировал RazrFalcon - 5.11.2011, 16:39
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 5.11.2011, 18:38
Сообщение #2


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Пока что остановился на таком варианте:
for (int i = 0; i < list.count(); ++i) {
    MyThread *myTh = new MyThread();
    QThread *th = new QThread(this);
    connect(myTh,SIGNAL(done()),th,SLOT(quit()));
    connect(th,SIGNAL(finished()),this,SLOT(workFinished()));
    myTh->moveToThread(th);
    th->start();
}
и
void MainWindow::workFinished()
{
    QThread *th = qobject_cast<QThread *>(sender());
    if (th)
        delete th;

    QList<QThread *> list = findChildren<QThread *>();
    if (list.isEmpty())
        qDebug()<<"all thread finished";
}


Нормальное решение? Вроде пашет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 10.11.2011, 14:40
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


    QThread *th = qobject_cast<QThread *>(sender());
    if (th)
        delete th;


не следует удалять сигнальщика в слоте. для этого есть deleteLater()
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 10.11.2011, 15:38
Сообщение #4


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Цитата(PAFOS @ 10.11.2011, 13:40) *
не следует удалять сигнальщика в слоте. для этого есть deleteLater()

deleteLater() - удаляет слишком поздно =/
У меня с ним список ниже не пустой. А должен быть пустой!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 16.11.2011, 8:12
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


ну а иначе рискуешь получить Segfauilt в неожиданном месте.

Создай отдельный список и храни там указатели на потоки
в слоте workFinished()

QThread *th = (QThread*)sender();
th->deleteLater();
listOfThreads.removeOne(th);

if( listOfThreads.isEmpty() )
   qDebug() << "all thread finished";


th->deleteLater(); - после этого указатель на QThread уже можно терять.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 16.11.2011, 8:20
Сообщение #6


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Сегфолтов пока не наблюдал.
Плодить кучу переменых/списков нет желания. Люблю там где нужно получать переменные.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 18.11.2011, 18:11
Сообщение #7


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


нашел еще один способ:
delete(th);
Не знаю в чем разница между
delete th;
но результат то же.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 10.1.2012, 10:53
Сообщение #8





Гости








    


RazrFalcon, cскажите как узнаёте сколько ядер в системе?
Спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 14.1.2012, 0:35
Сообщение #9


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Цитата(Гость @ 10.1.2012, 10:53) *
RazrFalcon, cскажите как узнаёте сколько ядер в системе?
Спасибо.

QThread::idealThreadCount()
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 16.1.2012, 12:19
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Хм, ну, как оно там точно организовано в ядре Линуксов, это я не знаю, но в Виндоус есть еще такая тонкость: мало насоздавать потоков (процессов) по числу ядер, надо еще не забыть привязать каждый поток/процесс к конкретному ядру. Там для этого предусмотрены специальные функции типа SetThreadAffinityMask() или что-то подобное (лезть в MSDN и уточнять сейчас лень). В противном случае, планировщик все равно имеет возможность по своему усмотрению перекидывать потоки с ядра на ядро, со всеми сопутствующими накладными расходами, - а оно тебе надо?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 27.11.2024, 16:50