Класс, который вы написали, создает поток и инициализирует QObject :: timer. Затем он вызывает вызываемую пользователем функцию init (), а затем функцию QThread :: exec () .
- Я предполагаю, что вы предполагали, что exec () будет пользовательской функцией, в которой должна выполняться реальная работа. Имейте в виду, что QThread :: exec () обрабатывает очередь событий Qt потока.
- Кроме того, на некоторых платформах может появиться предупреждение «Ошибка создания таймера из потока». Я столкнулся с этой ошибкой в Windows, когда код прекрасно выполнялся в Linux
- Также помните, что ваш таймер никогда не будет срабатывать, если вы не вызовете функцию QThread :: exec () или QApplication :: processEvents () изнутри вашего потока.
Контекст потока в Qt такой же, как и любой другой концепт потока. То есть вся память распределяется между многопоточным кодом (введенным в этот момент в вашей функции «run ()»). И любой другой контекст, который вызывает ваш объект. Если этот объект когда-либо выполняется в потоке и доступен извне потока, вы должны защитить общие данные.
- Поскольку все данные совместно используются контекстами потоков (это модель многопроцессорной обработки с общей памятью), проблем с вызовом функций до / после / во время выполнения потока не возникает. При условии:
- Объект полностью построен перед вызовом любого метода. Это не обязательно для потоков, обязательно, если объект не создан в потоке.
- Любой элемент данных защищен блокировкой мьютекса (об этом я говорил в # 2). QMutexLocker - это удобный RAII-способ работы с мьютекс-блокировками в Qt.
Я полагаю, что я полностью ответил на ваш вопрос здесь, поэтому я продолжу ссылаться на RAII и Threading статей, которые я написал на другом сайте, просто для дальнейшего ознакомления.
Редактировать: специфичность сценариев потоков:
class MyThreadedClass : public QThread
{
MyThreadClass(const boost::shared_ptr<SomeOtherClass> &t_object)
: m_object(t_object) {}
void doSomething()
{
// Depending on how this method was called (from main, from internal thread)
// will determine which thread this runs on, potentially complicating thread
// safety issues.
m_object->someThing();
}
void run()
{
// I'm now in a thread!
m_object->someFunction(); // oops! The call to someFunction is occurring from
// a thread, this means that SomeOtherClass must be
// threadsafe with mutex guards around shared
// (object level) data.
// do some other stuff
}
};
int main()
{
MyThreadClass thread(someobjectfromsomewhere);
thread.start(); // MyThreadClass is now running
thread.doSomething(); // The call to doSomething occurs from main's thread.
// This means 2 threads are using "thread", main
// and "thread"'s thread.
// The call to thread.doSomething hits Thread.m_object, which means that
// now multiple threads are also accessing m_object ("thread" and "main").
// This can all get very messy very quickly. It's best to tightly control
// how many threads are hitting an object, and how
}
- ПРИМЕЧАНИЕ. Было бы неплохо изучить QFuture , который предназначен для обработки асинхронных задач такого типа, как кодировщик, которых вы смотрите QFuture позволит избежать некоторые из потенциальных проблем с потоками общих данных и взаимоблокировок.