Russian Qt Forum

Qt => Вопросы новичков => Тема начата: lucky от Февраль 19, 2011, 22:18



Название: Вопрос по синхронизации потоков
Отправлено: 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 и не было бы никакой разницы?


Название: Re: Вопрос по синхронизации потоков
Отправлено: SimpleSunny от Февраль 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. Внимательней глянул на ваш код, в этом случае вам не нужна синхронизация, так как нет общих данных которые следует защищать.


Название: Re: Вопрос по синхронизации потоков
Отправлено: Fat-Zer от Февраль 19, 2011, 22:56
в данном случае pow
а) можно сделать статическим, ибо вы оперируете данными только на стеке
б) вообще не использовать блокировки, по той же причине.
в) лучше использовать любую стандартную pow


Название: Re: Вопрос по синхронизации потоков
Отправлено: lucky от Февраль 19, 2011, 23:00
pow использовал просто ради примера. Как говориться, что в голову первое пришло :). Это не сильно важно. Для меня важно другое.
SimpleSunny благодарю, что ответили. Вы сказали, что у меня нет общих данных, которые можно было бы защитить. А в методе pow код же используется двумя потоками одновременно, его что ли не нужно защищать? Уточните пожалуйста.


Название: Re: Вопрос по синхронизации потоков
Отправлено: SimpleSunny от Февраль 19, 2011, 23:20
Его защищать не нужно, так как изменяются только локальные (которые созданы на стеке) переменные, для каждого потока они будут своими.

Если бы, допустим, в ThreadDialog была объявлена приватная переменная res, а в коде выше отсутствовала строка quint32 res(1);. Тогда переменная res была бы общей для этих потоков и общение (чтение, запись) с ней необходимо было бы защищать.


Название: Re: Вопрос по синхронизации потоков
Отправлено: lucky от Февраль 19, 2011, 23:27
Не подумал как то, точно. SimpleSunny и Fat-Zer большое спасибо.