Russian Qt Forum
Апрель 25, 2024, 07:05 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вопрос по синхронизации потоков  (Прочитано 4215 раз)
lucky
Гость
« : Февраль 19, 2011, 22:18 »

Создал метод в классе ThreadDialog, который является наследником от QDialog:
Код:
quint32 ThreadDialog::pow(quint32 x, quint32 n)
{
    lock.lockForWrite();
    //QMutexLocker locker(&mutex);

    quint32 res(1);
    for(quint32 i = 0; i < n; i++)
        res *= x;

    lock.unlock();

    return res;
}

В этом классе создал два объекта от класса Thread, который является наследником от QThread:
Код:
    threadA.setData(this, "Thread #1", 2, 30);
    threadB.setData(this, "Thread #2", 2, 20);

И теперь в методе run() я вызываю метод pow:
Код:
void Thread::run()
{
    qDebug() << nameThread << ":" << dialog->pow(x, n);
}

Как видно два потока обращаются к методу pow. Я вычитал с книги Бланшета, что лучше для производительности использовать QReadWriteLock чем QMutex. Вопрос в следующем, правильно ли я использовал lockForWrite();? Т.е. в данной задаче это сделано правильно или можно было использовать QMutex и не было бы никакой разницы?
Записан
SimpleSunny
Гость
« Ответ #1 : Февраль 19, 2011, 22:43 »

В данном случае будет все равно что использовать или QMutex, или QReadWriteLock.
QReadWriteLock эффективен, когда часто читается и редко пишется.

Данные с которыми работают QThread было бы логичней вывести в отдельный класс, чтобы не передавать в поток всю форму, к тому же можно избежать потенциальных ошибок.

Похожие темы можно найти на форуме.
К примеру http://www.prog.org.ru/topic_14426_0.html

UPD
P.S. Для возведения в степень есть оптимальней алгоритмы.
P.P.S. Будет быстрей, если сначала возвести в степень число, результат запомнить в локальную переменную, и только потом под mutex'ом уже сделать присваивание общей переменной.
P.P.P.S. Внимательней глянул на ваш код, в этом случае вам не нужна синхронизация, так как нет общих данных которые следует защищать.
« Последнее редактирование: Февраль 19, 2011, 22:52 от SimpleSunny » Записан
Fat-Zer
Гость
« Ответ #2 : Февраль 19, 2011, 22:56 »

в данном случае pow
а) можно сделать статическим, ибо вы оперируете данными только на стеке
б) вообще не использовать блокировки, по той же причине.
в) лучше использовать любую стандартную pow
Записан
lucky
Гость
« Ответ #3 : Февраль 19, 2011, 23:00 »

pow использовал просто ради примера. Как говориться, что в голову первое пришло Улыбающийся. Это не сильно важно. Для меня важно другое.
SimpleSunny благодарю, что ответили. Вы сказали, что у меня нет общих данных, которые можно было бы защитить. А в методе pow код же используется двумя потоками одновременно, его что ли не нужно защищать? Уточните пожалуйста.
Записан
SimpleSunny
Гость
« Ответ #4 : Февраль 19, 2011, 23:20 »

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

Если бы, допустим, в ThreadDialog была объявлена приватная переменная res, а в коде выше отсутствовала строка quint32 res(1);. Тогда переменная res была бы общей для этих потоков и общение (чтение, запись) с ней необходимо было бы защищать.
Записан
lucky
Гость
« Ответ #5 : Февраль 19, 2011, 23:27 »

Не подумал как то, точно. SimpleSunny и Fat-Zer большое спасибо.
« Последнее редактирование: Февраль 19, 2011, 23:30 от lucky » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 20.