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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Правильное использование QReadWriteLock, QMutex  (Прочитано 9129 раз)
thechicho
Гость
« : Ноябрь 02, 2011, 21:13 »

помогите разобраться.
в главном потоке создается 100500 потоков.
в каждом новом потоке результат записывается в файл.

Как правильно сделать защиту?

Код
C++ (Qt)
QReadWriteLock lock;
 
void WriterThreadN::run()
{
    ...
    lock.lockForWrite();
    write_file();
    lock.unlock();
    ...
}

так верно?
просто Авварон написал http://www.prog.org.ru/index.php?topic=19803.msg134008#msg134008
но я не догоняю в чем ошибка и как реализовать правильно.

еще. в гуи потоке вставляю результат:
Код
C++ (Qt)
void MainThread::resultSlot(QString &result)
{
   QStandardItem *itemResult = new QStandardItem(result);
   model->appendRow(itemResult);
 
//    model->insertRow(0);
//    model->setData(model->index(0, 0), result);
}

так достаточно будет для защиты?
Код
C++ (Qt)
void MainThread::resultSlot(QString &result)
{
   // QMutex mutex; // объявлю в .h
   mutex.lock();
   QStandardItem *itemResult = new QStandardItem(result);
   model->appendRow(itemResult);
   mutex.unlock();
 
//    model->insertRow(0);
//    model->setData(model->index(0, 0), result);
}

Хелп плз понять.
« Последнее редактирование: Ноябрь 02, 2011, 21:15 от thechicho » Записан
popper
Гость
« Ответ #1 : Ноябрь 02, 2011, 22:00 »

Если все вторичные потоки являются объектами одного класса (WriterThreadN), то QReadWriteLock лучше объявить в приватной секции этого класса. Использование локкера в теле функции run формально правильное.
Сомнение вызывает число потоков 100500 (даже 100-500).
Неужели разрабатываемая программа предназначена для ПК?
Записан
thechicho
Гость
« Ответ #2 : Ноябрь 02, 2011, 22:45 »

// Если все вторичные потоки являются объектами одного класса
м. т.е. в главном в прайвит объявляю QReadWriteLock и могу без проблем использовать лок/анлок в потоках.
// (WriterThreadN)
в данном контексте, если я Вас правильно понял, то (MainThread)
// Использование локкера в теле функции run формально правильное.
а как надо делать правильно то? просто я впервые с этим сталкиваюсь, не понимаю сам принцип как оно работает.

100500 = http://lurkmore.ru/%D0%A1%D1%82%D0%BE%D0%BF%D0%B8%D1%86%D0%BE%D1%82 Веселый

более менее прояснилось, буду пробовать. спс за ответ Улыбающийся
Записан
thechicho
Гость
« Ответ #3 : Ноябрь 02, 2011, 22:47 »

11000100010010100  Веселый
Записан
thechicho
Гость
« Ответ #4 : Ноябрь 02, 2011, 22:49 »

#define CTO500 0x7FFFFFFF  Веселый
Записан
andrew.k
Гость
« Ответ #5 : Ноябрь 02, 2011, 23:03 »

Threaded Programming with Qt
Записан
thechicho
Гость
« Ответ #6 : Ноябрь 03, 2011, 14:00 »

сенкс, посмотрел, ток легче не стало Улыбающийся

// м. т.е. в главном в прайвит объявляю QReadWriteLock и могу без проблем использовать лок/анлок в потоках.
фиг там. если в главном объявить, то в run() потока не видно. объявил в прайвит класса потока, добавил в run() локеры, вроде работает. по крайней мере из 400++ попыток, норм записало в файл данные, а вчера без локера, пара строк не дописалась  Веселый

но я все равно не пойму, Авварон, где я не прав то? что ты там про стек говорил, объясни, плиз.
Записан
thechicho
Гость
« Ответ #7 : Ноябрь 03, 2011, 14:10 »

кажется, понял.
ты имел в виду, что QMutex mutex; надо объявить в .h ?

у меня там было в run() в смысле в стеке...
Код
C++ (Qt)
void BeelinerThread::run()
{
   //qDebug() << "Thread" << iter << QObject::thread();
   QMutex mutex;

ребят объясните, а какая разница? что я в .h объявлю или в .cpp ?
все равно получается, что у каждого потока (объекта потока) будет свое объявление QMutex mutex; (QReadWriteLock lock;) ... эээ... что-то я запутался  Непонимающий
если у каждого свой QReadWriteLock lock, то синхронизации же не будет получается... т.е. толку не будет от них? почему тогда ща норма записалось... просто повезло?
объясните на пальцах как правильно сделать ааааа?  В замешательстве
Записан
Bepec
Гость
« Ответ #8 : Ноябрь 03, 2011, 14:21 »

Оффтоп:
Эх ненравится мне твоя аватара, сменил бы.

По делу - мьютексы делают простую вещь - они блокируют все, что находится между ними. (lock/unlock)

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

О чем хотел сказать аваррон спроси у него самого в ЛС(личные сообщения).

Я же лично использую 1 мьютекс на 1 класс, не больше.

Проще говоря - у тебя потоки сейчас по идее защищены (весь код не смотрел, нет времени, но если так как в
Код:
void BeelinerThread::run()
, то правильно).

Защиту на добавление сам решай - нужно тебе ставить или нет.

PS Синхронизация - это когда только 1 поток может работать с переменной. Остальные в это время ждут и прочая прочая прочая.

Уточняю - Если у тебя стоит мьютекс на добавление, то если обратятся 2 потока, то первый поставит мьютекс, а второй впадет в спячку, пока первый не снимет мьютекс. Кстати это тоже опасно. Чем именно узнаешь потом Улыбающийся


« Последнее редактирование: Ноябрь 03, 2011, 14:29 от Bepec » Записан
thechicho
Гость
« Ответ #9 : Ноябрь 03, 2011, 15:19 »

это со скайпа ава Улыбающийся
(finger) напиши там, увидишь Веселый

просто у меня пустые строки там вставлялись, я думал это из-за одновременной вставки 0 строки. поэтому решил поставить мьютекс, ток, походу неправильно там делал.

защита на запись уже в другой проге. ну ок, значит оставляю как есть, если криво будет писать, Верес с тебя дебаг  Показает язык
сенкс, за ответ Улыбающийся
Записан
thechicho
Гость
« Ответ #10 : Ноябрь 03, 2011, 15:36 »

http://developer.qt.nokia.com/videos/watch/enhancing_your_qt_application_with_multiple_threads
30:10
static QMutex mutex;
 Непонимающий
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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