Qt-сигналы (QueuedConnection и DirectConnection)

У меня проблемы с сигналами Qt.

Я не понимаю, как QueuedConnection DirectConnection и QueuedConnection ?

Я был бы благодарен, если кто-нибудь объяснит, когда использовать какой из них (пример кода будет оценен).

    Вы не увидите большой разницы, если не работаете с объектами, имеющими разные сходства нитей. Предположим, у вас есть QObjects A и B и они оба прикреплены к различным streamам. A имеет сигнал под названием somethingChanged() а B имеет слот под названием handleChange() .

    Если вы используете прямое соединение

     connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection ); 

    метод handleChange() будет фактически выполняться в streamе A В принципе, как будто излучение сигнала вызывает метод «прямо». Если B::handleChange() не является streamобезопасным, это может привести к некоторым (трудным для поиска) ошибкам. По крайней мере, вам не хватает преимуществ дополнительной нити.

    Если вы измените метод подключения на Qt::QueuedConnection (или, в этом случае, пусть Qt решит, какой метод использовать), все становится более интересным. Предполагая, что stream B запускает цикл событий, излучение сигнала отправляет событие в цикл событий B Цикл событий останавливает событие и в конечном итоге вызывает метод слота всякий раз, когда управление возвращается к нему (это цикл события). Это делает довольно простой способ связи между / между streamами в Qt (опять же, если ваши streamи запускают собственные локальные циклы событий). Вам не нужно беспокоиться о блокировках и т. Д., Потому что цикл событий сериализует вызовы слота.

    Примечание. Если вы не знаете, как изменить сходство streamов QObject, загляните в QObject::moveToThread . Это должно заставить вас начать.

    редактировать

    Я должен уточнить свое вступительное предложение. Это имеет значение, если вы указываете соединение в очереди – даже для двух объектов в одном streamе. Событие по-прежнему отправляется в цикл событий streamа. Таким образом, вызов метода по-прежнему является асинхронным, то есть он может задерживаться непредсказуемыми способами (в зависимости от любых других событий, которые цикл может потребовать для обработки). Однако, если вы не укажете метод подключения, прямой метод автоматически используется для соединений между объектами в одном streamе (по крайней мере, в Qt 4.8).

    в дополнение к Jacob Robbins ответ:

    утверждение «вы не увидите большой разницы, если вы не работаете с объектами, имеющими разные сходства нитей», неверно ;

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

    излучение сигнала в очередь в одном streamе вызовет вызов в цикл событий streamов, поэтому выполнение всегда будет задерживаться.

    Класс, основанный на QObject, имеет статическое соединение с самим собой

    Ответ Джейкоба потрясающий. Я просто хотел бы добавить сравнительный пример для встроенного программирования.

    Исходя из встроенного фона RTOS / ISR, было полезно увидеть сходство в DirectConnection Qt с превентивным поведением ISR и QueueConnection Qt для сообщений в очереди в RTOS между задачами.

    Боковое примечание. Исходя из встроенного фона, мне сложно определить поведение в программировании. Я никогда не оставляю аргумент как Авто, но это только личное мнение. Я предпочитаю, чтобы все было явно написано, и да, что становится трудным время от времени!

    Давайте будем гением компьютера.