Название: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: thechicho от Февраль 05, 2014, 14:27 Допустим в главном потоке есть переменная QStringList tmp;
Через определенный промежуток времени в этом потоке вызывается слот (slot1), в котором эта переменная перезаписывается (tmp = tmpList;). Так же работает n-ое количество потоков, созданных в главном потоке. Эти потоки многократно вызывают слот (slot2) в главном потоке в произвольный момент времени, в котором рассматриваемая переменная модифицируется (tmp.takeFirst();); Вопрос - может ли в один момент времени произойти доступ к переменной из разных слотов? То есть слоты (и обычные функции?) обрабатываются в главном потоке всегда последовательно или могут обрабатываться одновременно, т.к. вызываются из разных мест в произвольное время. Нужен мьютекс или нет: void MainThread::slot1(QStringList tmpList) { mutex.lock(); tmp = tmpList; mutex.unlock(); } void MainThread::slot2() { mutex.lock(); QString str = tmp.takeFirst(); mutex.unlock(); } кроме ответа на вопрос буду благодарен за ликбез или ссылку на статью по теме. не вообще про многопоточность, а именно по этому контексту. Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Serr500 от Февраль 05, 2014, 19:40 слоты (и обычные функции?) обрабатываются в главном потоке всегда последовательно или могут обрабатываться одновременно, т.к. вызываются из разных мест в произвольное время. В главном потоке ничего не может обрабатываться одновременно. Одновременно могут идти обработки только в разных потоках. Пока в рамках цикла сообщений выполняется одна функция, другая не может быть выполнена. Иными словами, если запустился на обработку слот, другой слот не начнёт обработку до тех пор, пока первый не закончит свою работу. Однако, если внутри слота выполнить QCoreApplication::processEvents, то в этот момент вполне может быть запущен на выполнение другой слот.Через определенный промежуток времени в этом потоке вызывается слот (slot1), в котором эта переменная перезаписывается (tmp = tmpList;). Вопрос поставлен немного некорректно, поскольку ответ на него зависит от типа соединений сигналов и слотов. Если рассматривать все варианты, то да, может.Так же работает n-ое количество потоков, созданных в главном потоке. Эти потоки многократно вызывают слот (slot2) в главном потоке в произвольный момент времени, в котором рассматриваемая переменная модифицируется (tmp.takeFirst();); Вопрос - может ли в один момент времени произойти доступ к переменной из разных слотов? Дело здесь в том, как именно вызываются слоты. Если слот вызывается как обычная функция Код: obj1->slot1(); Если слот вызывается через сигнал Код: connect(this, SIGNAL(signal1()), obj1, SLOT(slot1())); P.S. Вместо Код: mutex.lock(); Код: { Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: thechicho от Февраль 06, 2014, 19:09 а если в потоке (worker) выполняется какая-то длительная по времени функция и во время ее выполнения из другого (главного) потока приходит сигнал, соединенный (без указания типа соединения) с слотом в потоке (worker). то этот слот выполнится до завершения выполнения функции (говорю по опыту).
но, когда будет выполняться этот слот, функция приостановит свою работу или они выполнятся одновременно? то есть: в функции и слоте есть одна глобальная переменная. нужно ли использовать мьютекс в слоте при доступе к этой переменной? ведь когда в слоте происходит доступ к переменной, в фукнции тоже может в этот же момент времени произойти доступ к этой переменной? то есть если я использую мьютекс, то при одновременном выполнении функции и слота, функция должна приостановить свою работу, пока мьютекс в слоте не разблокируется. тем самым переменная будет защищена от одновременного доступа из функции и слота. или как это все работает? ??? Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Serr500 от Февраль 06, 2014, 21:50 а если в потоке (worker) выполняется какая-то длительная по времени функция и во время ее выполнения из другого (главного) потока приходит сигнал, соединенный (без указания типа соединения) с слотом в потоке (worker). то этот слот выполнится до завершения выполнения функции (говорю по опыту). Посмотрите на currentThread(). Наверняка слот выполнился в главном потоке. Т.е. вызов был типа Qt::DirectConnection.но, когда будет выполняться этот слот, функция приостановит свою работу или они выполнятся одновременно? В рамках одного потока одновременное выполнение невозможно. Функция не может приостановить работу, только если она не была специально так спроектирована (ну, или случайно... ;) ). Если слот вызван из другого потока, то возможно только две ситуации:1) Вызов слота встал в очередь потока worker. Слот будет выполнен при возврате к циклу сообщений, т.е. после завершения функции. 2) Слот выполнился внутри главного потока. В этом случае выполнение одновременное. то есть если я использую мьютекс, то при одновременном выполнении функции и слота, функция должна приостановить свою работу, пока мьютекс в слоте не разблокируется. тем самым переменная будет защищена от одновременного доступа из функции и слота. Да. Но только если функция и слот будут работать в разных потоках. Похоже, в Вашем случае это именно так. Если поток один -получите "мёртвую блокировку".По-моему, Вас вводит в заблуждение слово "слот". Забудьте про него. Слот - это такая же функция. Просто для неё можно применить другие методы вызова. Но этот метод - всего лишь хитрая обёртка, которая в итоге вызовет эту функцию. И как любая функция она может выполниться внутри любого потока. Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Igors от Февраль 07, 2014, 11:15 Слот - это такая же функция. Просто для неё можно применить другие методы вызова. Но этот метод - всего лишь хитрая обёртка, которая в итоге вызовет эту функцию. И как любая функция она может выполниться внутри любого потока. По ходу дела вопрос - а само Qt защищает вызов слота мутексом или нет?Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Johnik от Февраль 07, 2014, 12:10 По ходу дела вопрос - а само Qt защищает вызов слота мутексом или нет? Если используется механизм Qt (invoke, или сигнал), второй вызов этого же слота отработает после текущего, если вызван просто как метод, то тут уж сам себе злобный буратино.Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Igors от Февраль 07, 2014, 12:27 Если используется механизм Qt (invoke, или сигнал), второй вызов этого же слота отработает после текущего, если вызван просто как метод, то тут уж сам себе злобный буратино. Ну с Буратино ясно, но-все-таки четкого ответа не прозвучало - защищены или как? Может ли слот выполняться одновременно (разумеется разными нитками)?Название: Re: Нужно ли блокировать доступ к переменной Отправлено: Johnik от Февраль 07, 2014, 12:37 Если объекты принадлежат разным тредам, то да, почему бы и нет.
Один объект не может принадлежать нескольким тредам одновременно. Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Igors от Февраль 07, 2014, 12:43 Если объекты принадлежат разным тредам, то да, почему бы и нет. Наверное Вы больше склонны к гуманитарным вещам (живопись, музыка) чем к техническим где есть четкое Да/Нет :)Название: Re: Нужно ли блокировать доступ к переменной Отправлено: Johnik от Февраль 07, 2014, 12:56 Наверное Вы больше склонны к гуманитарным вещам (живопись, музыка) чем к техническим где есть четкое Да/Нет :) Вы обо мне ничего не знаете, чтоб делать такие выводы.Я же вижу, что очень многие недопонимают работу с многопоточными алгоритмами. Еще раз: 1. Есть объект (класс которого унаследован от QObject). Объект принадлежит одному потоку. Как запустить слот 2 раза механизмом Qt, чтоб "каждый запуск" выполнялся одновременно. Ответ: НИКАК. 2. Есть 2 объекта, принадлежат одному потоку. Даже тут может одновременно выполняться только один слот в контексте одного объекта единомоментно. 3. Есть 2 объекта, и 2 потока, соответственно может выполняться слот одновременно в каждом потоке, каждый в контексте своего объекта. PS. В Qt довольно грамотно сделана работа с потоками, по сравнению с другим инструментами (Java, .net, а с ними я тоже работал) /это мое личное мнение/. Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Serr500 от Февраль 07, 2014, 18:19 По ходу дела вопрос - а само Qt защищает вызов слота мутексом или нет? Не могу ответить на этот вопрос. Какие-то объекты синхронизации там есть, но глубоко в "потроха" сигнал-слотового механизма я не залезал.Я же вижу, что очень многие недопонимают работу с многопоточными алгоритмами. Вы тоже недопонимаете работу с многопоточными алгоритмами. Можно. А как именно - это Вам простенькая задачка. ;)Еще раз: 1. Есть объект (класс которого унаследован от QObject). Объект принадлежит одному потоку. Как запустить слот 2 раза механизмом Qt, чтоб "каждый запуск" выполнялся одновременно. Ответ: НИКАК. Название: Re: Нужно ли блокировать доступ к переменной в главном потоке (QMutex)? Отправлено: Igors от Февраль 07, 2014, 19:47 Не могу ответить на этот вопрос. Какие-то объекты синхронизации там есть, но глубоко в "потроха" сигнал-слотового механизма я не залезал. Аналогично. Я видел мутекс вроде используемый даже при DirectConnection но что он делает - не знаючтоб "каждый запуск" выполнялся одновременно. Ответ: НИКАК. Не понимаю что имеется ввиду (чтоб "каждый запуск" выполнялся одновременно) ??? |