2016-06-01 2 views
1

Я знаю, что не разрешено вызывать функцию другого потока в Mainthread. Разрешено ли вызывать сигнал из другого потока без каких-либо проблем? Допустим, что этот код находится в MainWindow:QThread сообщить threadsafe

thread-> moveTOThread (obj); emit obj-> Signal();

спасибо


или это путь:

Obj.h 
signals: 
    void testSignal(); 
public slots: 
void Func(); 

    MainWindow.h 
    void testSignal(); 

    MainWindow.cpp 
    thread->moveTOThread(obj); 
    connect(this,SIGNAL(testSignal()),obj,SIGNAL(testSignal())); 
    emit testSignal(); 

    Obj.cpp 
    connect(this,SIGNA(testSignal()),this,SLOT(Func())); 

ответ

0

Я не 100% уверен, что произойдет, если вы сделаете это. Тем не менее, вы все еще пересекаете/ломаете границу потока - и, вероятно, сигнал будет испускаться из потока, который вы вызываете, испускаете.

Я считаю, что лучший подход заключается в подключении сигнала в вашем «вызывающем» объекте к сигнал в вашем целевом объекте. Но даже это немного плохо в том, что сигнал сразу испускается (возможно, это ваше намерение), что похоже на сигнал прямого соединения, который по моему мнению, очень плохо, если у вас нет очень веской причины (Я не могу думать ни о чем).

Но почему бы просто не подключить сигнал к слоту в вашем объекте, который затем излучает ваш сигнал. Таким образом, вы сохраняете границу потока?

Похоже, вы пытаетесь заставить сигнал в другом потоке немедленно запускать ... что такое ваш прецедент?

+0

Я просто хочу как-то вызвать функцию obj. Поскольку obj-> Func(); не является потокобезопасным. Я ищу потоковый режим. Я могу испустить сигнал от obj и подключить этот сигнал в obj-конструкторе к Slot Func(). Как я могу назвать Func() threadsafe ???? – Bob

+0

@Bob Предполагая, что «класс B» является объектом, живущим в другом потоке, просто подключите сигнал от «класса A» к слоту в «классе B». Вам не нужно подключать сигнал из класса «B» к слоту в «классе B», а затем вызывать этот сигнал. – thuga

+0

@Bob well ... вы можете просто вызвать эту функцию напрямую, если хотите, вас никто не остановит. Но он нарушает границу потока и не безопасен для этого. Чтобы безопасно вызвать функцию объекта, механизм должен отправить сигнал ... его как две строки кода дополнительно! Одна линия для подключения, одна линия, чтобы излучать сигнал (о да, и вам нужно объявить сигнал) ... вот и все! то вся эта суета уходит.Альтернативно, если это какая-то «вспомогательная» функция, в которой вам не нужен экземпляр объекта, вы можете сделать его статической функцией ... что ваш прецедент? или что делает ваша функция? –

2

connect принимает 5-й аргумент, который является типом соединения. Значение по умолчанию, AutoConnection, будет использовать безопасный поток QueuedConnection тип соединения, предполагая, что объекты были в разных потоках при вызове соединения. Если они находятся в одном потоке при подключении, он будет использовать соединение типа non threadsafe DirectConnection.

Решение проблемы обеспечивается путем очередности вызова слота в качестве события, вызывающего его в потоке назначения, когда управление возвращается в цикл событий.

+0

Когда вы используете ['Qt :: AutoConnection'] (http://doc.qt.io/qt-5/qt.html#ConnectionType-enum), проверка выполняется, когда сигнал испускается, а не когда соединение сделан. – thuga

4

Да! Сигнал можно вызывать из любого потока, если вы используете автоматическое соединение по умолчанию с сигналом. Такие слоты/функторы будут исполнять в потоке контекста объекта. Например, вы можете передавать сигналы от обратных вызовов из сторонних библиотек, даже если эти библиотеки не используют Qt.

Предупреждение: Любые явно подключенные слоты/функторы будут выполняться в потоке, где был вызван сигнал.

+0

Знаете ли вы, что такое вызов для вызова функции из другого потока? Почему бы просто не вызвать функцию из другого объекта потоков из main-gui-thread? Я не вижу проблем, если я только вызываю функции из других потоков оттуда? – Bob

+0

@Bob Если функции, которые вы вызываете, не являются потокобезопасными, вы сталкиваетесь с неопределенным поведением. Вы можете «видеть» без проблем, но вы можете без форматирования жесткого диска. –

+0

Idk Я не получаю ответа. Могу ли я вызвать функцию другого потока без моих программных сбоев? Почему я должен использовать Signal и Slots, когда его дополнительный код. – Bob