Путаница с использованием потоков Qt - PullRequest
1 голос
/ 19 ноября 2011

Так что, если я правильно понимаю, если у меня есть класс FunctionsClass, который наследует QObject, и я установил этот класс на Qthread с именем FunctionClassThread, выполнив:

FunctionsClass classObj; 
classObj.moveToThread( &FunctionClassThread );
FunctionClassThread.start();

Насколько я понимаю, этот метод настройки потока будет обрабатывать только выполнение слотов в FunctionsClass, что означает, что поток, выполняющий FunctionsClass, может быть заблокирован, если слот в FunctionsClass по какой-либо причине имеет бесконечный цикл.

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

Ответы [ 2 ]

1 голос
/ 19 ноября 2011

Когда вы выполняете метод объекта, он выполняется в потоке, в котором вы вызываете метод.Неважно, где находится QObject.

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

Это можно сделать с помощью сигналов и слотов при обычном соединении.Если вы не хотите использовать этот механизм, вы можете использовать QMetaObject , но вам все равно нужно объявить их как слоты.Статический метод invokeMethod, если он вызывается с помощью Qt :: QueuedConnection, вызывает метод в потоке, в котором находится объект, владеющий этим методом.Вы также можете передавать аргументы методу и возвращать значения из него.

Учтите, что любые типы данных, которые вы хотите иметь возможность передавать из потока в другой, должны быть зарегистрированы с помощью qRegisterMetaType идолжны соблюдать условия, указанные там.

0 голосов
/ 19 ноября 2011

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

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

Имея много дополнительной работы, есть два других способа сделать то же самое. Во-первых, QThread s имеет цикл обработки событий, который запускается по умолчанию, если вы не переопределите run(). Вы можете создать пользовательских событий , которые вы можете опубликовать в цикле событий, который может инициировать действия в вашем классе, которые будут выполняться в контексте рабочего потока.

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

...