42 / 52 / 33
Регистрация: 15.12.2015
Сообщений: 199
|
|
1 | |
Получение сигнала во время работы функции-члена класса08.11.2017, 13:49. Показов 2710. Ответов 17
Метки нет (Все метки)
Добрый день!
Есть класс Dev с функцией-членом process(), внутри которой есть цикл while, выполняющийся пока член класса bool updated не равен true. Класс Dev дочерний класс от QObject, у него есть функция-член getData(), связанная при помощи connect с неким сигналом, внутри getData() член класса updated обращается в true. Мой вопрос в том, может ли быть вызвана getData(), во время выполнения process(), если они относятся к одному классу и будет ли когда нибудь завершена функция getData(). Буду благодарен если посоветуете хорошие материалы на эту тему.
0
|
08.11.2017, 13:49 | |
Ответы с готовыми решениями:
17
Можно ли сделать поле класса параметром функции-члена этого же класса? Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса? Функции в качестве члена класса Передача функции-члена класса в pthread_create |
7803 / 6567 / 2988
Регистрация: 14.04.2014
Сообщений: 28,706
|
|
08.11.2017, 15:32 | 2 |
Чётче пиши и лучше с заголовком класса. Он у тебя в отдельном потоке, что ли?
0
|
Заблокирован
|
|
08.11.2017, 15:52 | 3 |
Если getData - слот, тогда это хорошо, но он всё равно не будет вызываться, т.к. у тебя в функции process dead lock. Если ты хочешь, что бы во время вечного лупа в каком-то потоке (тебе кстати это лучше в другой поток двинуть) у тебя работали слоты, тебе где-нибуть вначале функции process нужно поставить
QApplication::processEvents() , но это очень плохая практика. Хорошая практика, это когда у тебя вообще нет никаких блокировок и твоя вечная функция process выполняется частями итеративно на каждый тик таймера.
1
|
348 / 203 / 52
Регистрация: 18.10.2017
Сообщений: 2,066
|
|
08.11.2017, 17:30 | 4 |
newbie_1, Смотря что и как делается в этом while, совершенно не обязательно он должен
захватывать весь ресурс процессора. Например, там что-то происходит по таймеру и регулярно проверяется флажок. Тогда и getData будет вызываться. Пётр.
1
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|
08.11.2017, 18:14 | 6 |
но фактически это опять же будет остановка process(), правда написанная непосредственно в коде этой функции в виде какого-то из sleep-ов.
Но лучше всё же разбить process() на итерации, и их запускать по таймеру, тогда будет заложена не только возможность прерывания выполнения программы, но и её корректного завершения между любыми итерациями выполнения (т.к. таймер можно всегда остановить, а вот запущенная функция будет продолжать оставаться в стеке до её завершения либо до выброса исключения).
1
|
348 / 203 / 52
Регистрация: 18.10.2017
Сообщений: 2,066
|
|
08.11.2017, 22:02 | 7 |
Так while() находится внутри потока process(), а getData() вне него. process() может сам проверять
этот флажок через указатель на данные, переданный ему при создании. Они же оба члены класса. Можно и в поток передавать значение переменной с помощью мьютекса, но тогда надо будет предпринимать меры, чтобы поток не останавливался. С помощью tryLock() или ещё как-нибудь, сейчас не помню, т.к. давно уже мьютексами не приходилось пользоваться. Пётр.
0
|
42 / 52 / 33
Регистрация: 15.12.2015
Сообщений: 199
|
|
15.11.2017, 07:30 [ТС] | 8 |
Спасибо всем за ответы, я решил что так делать не буду, но все таки, для
меня является интересным вопрос, может ли быть вызван слот принадлежащий классу, при выполнения метода этого класса? Вообще пока не могу прийти к нормальному пониманию механизма сигналов и слотов хотя все время их применяю. Может быть кто-то может посоветовать что почитать на эту тему?
0
|
7803 / 6567 / 2988
Регистрация: 14.04.2014
Сообщений: 28,706
|
|
15.11.2017, 09:19 | 9 |
0
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|
15.11.2017, 11:57 | 10 |
Если сигнал и слот в одном потоке, то работа сигналов-слотов аналогична вызову слота как метод класса. Если в разных потоках, то сигнал вместе с передаваемыми в нём данными (в аргументах) записывается в очередь, и потом из этой очереди считывается и обрабатывается вторым потоком.
0
|
42 / 52 / 33
Регистрация: 15.12.2015
Сообщений: 199
|
|
15.11.2017, 12:05 [ТС] | 11 |
А если выполняется определенный код, а в это время был сгенерирован сигнал, то связанный с ним слот будет выполнен немедленно, или после выполнения кода, который выполнялся до генерации сигнала?
0
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|
15.11.2017, 12:19 | 12 |
Сообщение было отмечено dopleref как решение
Решение
Если в одном потоке, или в connect принудительно выставлено
Qt::DirectConnection , то слот будет выполнен немедленно. Если в разных потоках, то слот обработается после того, как второй поток попадёт в цикл обработки эвентов (QEventLoop::exec() и прочие подобные ему, наподобие QThread::exec() ) и дойдёт очередь до его эвента. Есть ещё Qt::BlockingQueuedConnection, которая даст ещё и блокирование выдающего сигнал потока до завершения обработки эвента этого сигнала.http://doc.qt.io/qt-5/threads-qobject.html
1
|
42 / 52 / 33
Регистрация: 15.12.2015
Сообщений: 199
|
|
16.11.2017, 09:28 [ТС] | 13 |
TRam_, спасибо, это то что я хотел узнать!
0
|
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
|
|
10.06.2019, 00:57 | 14 |
А можно как-то принудительно во время выполнения метода обработать сигнал с другого потока,а потом продолжить действие метода?
0
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
|
10.06.2019, 11:58 | 15 |
ReYalp, нет, нельзя. Метод нужно разбивать на части, между которыми производилась бы обработка очередей событий. И только в этом месте он мог бы "останавливаться".
Добавлено через 2 минуты Самый простой способ - разделить один слот на несколько, и каждый последующий вызывать с помощью QTimer::singleShot
0
|
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
|
|
10.06.2019, 12:49 | 16 |
TRam_, окей, а как это сделать?
0
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
|
||||||
10.06.2019, 12:54 | 17 | |||||
????
0
|
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
|
|
10.06.2019, 13:17 | 18 |
Лучше так не делать. Тем более, что это точно не самый простой способ
Лучше в течение длительного метода понаставить вызовов qApp->processEvents(); : https://doc.qt.io/qt-5/qcoreap... cessEvents Этот вызов раскрутит текущие ожидающие события и выполнит их.Он специально для этого создан. Разбивать ничего не придется.
1
|
10.06.2019, 13:17 | |
10.06.2019, 13:17 | |
Помогаю со студенческими работами здесь
18
Проблемы с объявлением функции-члена класса Два коротких сигнала во время работы Windows (не при загрузке ПК) Вызов функции-члена класса по адресу в памяти Определить операторы как функции члена класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |